1 import moment from 'moment';
2 import PropTypes from 'prop-types';
3 import React from 'react';
4 import { Button } from 'react-bootstrap';
5 import { useTranslation } from 'react-i18next';
6 import { Link } from 'react-router-dom';
8 import Channels from './Channels';
9 import Crew from './Crew';
10 import MultiLink from './MultiLink';
11 import Players from './Players';
12 import Icon from '../common/Icon';
13 import { canApplyForEpisode, canRestreamEpisode } from '../../helpers/permissions';
14 import { withUser } from '../../helpers/UserContext';
16 const isActive = episode => {
17 if (!episode.start) return false;
19 const start = moment(episode.start).subtract(10, 'minutes');
20 const end = moment(episode.start).add(episode.estimate, 'seconds');
21 return start.isBefore(now) && end.isAfter(now);
24 const Item = ({ episode, onAddRestream, onApply, onEditRestream, user }) => {
25 const { t } = useTranslation();
30 'align-items-stretch',
36 if (isActive(episode)) {
37 classNames.push('is-active');
40 const style = React.useMemo(() => {
41 if (episode.event && episode.event.corner) {
43 backgroundImage: `url(${episode.event.corner})`,
47 }, [episode.event && episode.event.corner]);
49 const hasChannels = episode.channels && episode.channels.length;
50 const hasPlayers = episode.players && episode.players.length;
52 return <div className={classNames.join(' ')} style={style}>
53 <div className="episode-start me-3 fs-4 text-end">
54 {t('schedule.startTime', { date: new Date(episode.start) })}
56 <div className="d-flex flex-column flex-fill">
57 <div className="d-flex align-items-start justify-content-between">
59 {episode.title || episode.event ?
60 <div className="episode-title fs-4">
61 {episode.title || episode.event.title}
65 <div className="episode-comment">
70 <div className="episode-channel-links text-end">
73 channels={episode.channels}
75 onEditRestream={onEditRestream}
78 {!hasChannels && hasPlayers ?
79 <MultiLink players={episode.players} />
81 {onAddRestream && canRestreamEpisode(user, episode) ?
84 onClick={() => onAddRestream(episode)}
85 title={t('episodes.addRestream')}
86 variant="outline-secondary"
95 <Players players={episode.players} />
97 {(episode.crew && episode.crew.length)
98 || canApplyForEpisode(user, episode, 'commentary')
99 || canApplyForEpisode(user, episode, 'tracking') ?
100 <div className="mb-3">
101 <Crew episode={episode} onApply={onApply} />
105 <div className="episode-event mt-auto">
106 <Link className="event-link" to={`/events/${episode.event.name}`}>
107 {episode.event.title}
116 episode: PropTypes.shape({
117 channels: PropTypes.arrayOf(PropTypes.shape({
119 comment: PropTypes.string,
120 crew: PropTypes.arrayOf(PropTypes.shape({
122 event: PropTypes.shape({
123 corner: PropTypes.string,
124 name: PropTypes.string,
125 title: PropTypes.string,
127 players: PropTypes.arrayOf(PropTypes.shape({
129 start: PropTypes.string,
130 title: PropTypes.string,
132 onAddRestream: PropTypes.func,
133 onApply: PropTypes.func,
134 onEditRestream: PropTypes.func,
135 user: PropTypes.shape({
139 export default withUser(Item);