1 import PropTypes from 'prop-types';
2 import React from 'react';
3 import { Button, Col, Row } from 'react-bootstrap';
4 import { useTranslation } from 'react-i18next';
6 import CrewMember from './CrewMember';
7 import Icon from '../common/Icon';
8 import { compareCrew } from '../../helpers/Crew';
14 } from '../../helpers/Episode';
15 import { canApplyForEpisode } from '../../helpers/permissions';
16 import { useUser } from '../../hooks/user';
18 const Crew = ({ episode, onApply }) => {
19 const { t } = useTranslation();
20 const { user } = useUser();
22 const commentators = React.useMemo(() =>
23 episode.crew.filter(c => c.role === 'commentary').sort(compareCrew)
25 const trackers = React.useMemo(() =>
26 episode.crew.filter(c => c.role === 'tracking').sort(compareCrew)
28 const techies = React.useMemo(() =>
29 episode.crew.filter(c => c.role === 'setup').sort(compareCrew)
32 const sgLanguages = React.useMemo(() =>
33 getSGLanguages(episode)
36 const showCommentators = React.useMemo(() =>
37 commentators.length || (!hasPassed(episode) && (
38 canApplyForEpisode(user, episode, 'commentary') ||
39 hasSGRestream(episode)
41 , [commentators, episode, user]);
43 const showTracker = React.useMemo(() =>
44 trackers.length || (!hasPassed(episode) && (
45 canApplyForEpisode(user, episode, 'tracking') ||
46 hasSGRestream(episode)
48 , [episode, trackers, user]);
50 return <Row className="episode-crew">
53 <div className="fs-6 fs-md-5">
54 <Icon.MICROPHONE className="ms-3 me-2" title="" />
55 {t('episodes.commentary')}
57 {commentators.map(c =>
58 <CrewMember crew={c} key={c.id} />
60 {onApply && canApplyForEpisode(user, episode, 'commentary') ?
61 <div className="button-bar m-2">
63 onClick={() => onApply(episode, 'commentary')}
64 variant="outline-secondary"
70 {hasSGRestream(episode) ?
71 <div className="button-bar m-2">
72 {sgLanguages.map(lang =>
74 href={getSGSignupLink(episode, lang, 'commentator')}
77 variant="outline-secondary"
79 {`${t('episodes.sgSignUp')} ${lang.toUpperCase()}`}
88 <div className="fs-6 fs-md-5">
89 <Icon.MOUSE className="ms-3 me-2" title="" />
90 {t('episodes.tracking')}
93 <CrewMember crew={c} key={c.id} />
95 {onApply && canApplyForEpisode(user, episode, 'tracking') ?
96 <div className="button-bar m-2">
98 onClick={() => onApply(episode, 'tracking')}
99 variant="outline-secondary"
105 {hasSGRestream(episode) ?
106 <div className="button-bar m-2">
107 {sgLanguages.map(lang =>
109 href={getSGSignupLink(episode, lang, 'tracker')}
112 variant="outline-secondary"
114 {`${t('episodes.sgSignUp')} ${lang.toUpperCase()}`}
123 <div className="fs-6 fs-md-5">
124 <Icon.MONITOR className="ms-3 me-2" title="" />
125 {t('episodes.setup')}
128 <CrewMember crew={c} key={c.id} />
136 episode: PropTypes.shape({
137 channels: PropTypes.arrayOf(PropTypes.shape({
138 id: PropTypes.number,
140 crew: PropTypes.arrayOf(PropTypes.shape({
143 onApply: PropTypes.func,