1 import PropTypes from 'prop-types';
2 import React from 'react';
3 import { Button, Col, Container, Row } from 'react-bootstrap';
4 import { useTranslation } from 'react-i18next';
6 import ApplyButton from './ApplyButton';
7 import Scoreboard from './Scoreboard';
8 import ScoreChartButton from './ScoreChartButton';
9 import SettingsButton from './SettingsButton';
10 import ApplicationsButton from '../applications/Button';
11 import Protocol from '../protocol/Protocol';
12 import Rounds from '../rounds/List';
13 import Box from '../users/Box';
19 } from '../../helpers/permissions';
22 getTournamentMonitors,
26 hasTournamentMonitors,
27 } from '../../helpers/Tournament';
28 import { useUser } from '../../hooks/user';
30 const getClassName = (tournament, user) => {
31 const classNames = ['tournament'];
32 if (tournament.locked) {
33 classNames.push('is-locked');
35 classNames.push('is-active');
37 if (isRunner(user, tournament)) {
38 classNames.push('is-runner');
40 return classNames.join(' ');
48 const { t } = useTranslation();
49 const { user } = useUser();
51 return <Container className={getClassName(tournament, user)} fluid>
54 <div className="d-flex align-items-center justify-content-between">
55 <h1>{tournament.title}</h1>
56 <div className="button-bar">
57 <ApplicationsButton tournament={tournament} />
58 <ApplyButton tournament={tournament} />
59 {mayUpdateTournament(user, tournament) ?
60 <SettingsButton tournament={tournament} />
62 {mayViewProtocol(user, tournament) ?
63 <Protocol id={tournament.id} />
70 <Col lg={{ order: 2, span: 4 }} xl={{ order: 2, span: 3 }}>
71 <div className="tournament-sidebar">
72 {hasScoreboard(tournament) ? <>
73 <div className="d-flex align-items-center justify-content-between">
74 <h2>{t('tournaments.scoreboard')}</h2>
75 {hasRunners(tournament) && tournament.rounds.length > 2 ?
76 <ScoreChartButton tournament={tournament} />
79 {hasRunners(tournament) ?
80 <Scoreboard tournament={tournament} />
83 {hasTournamentAdmins(tournament) ?
85 <div className="d-flex align-items-center justify-content-between">
86 <h2>{t('tournaments.admins')}</h2>
88 {getTournamentAdmins(tournament).map(p =>
89 <p key={p.id}><Box user={p.user} /></p>
93 {hasTournamentMonitors(tournament) ?
95 <div className="d-flex align-items-center justify-content-between">
96 <h2>{t('tournaments.monitors')}</h2>
98 {getTournamentMonitors(tournament).map(p =>
99 <p key={p.id}><Box user={p.user} /></p>
105 <Col lg={{ order: 1, span: 8 }} xl={{ order: 1, span: 9 }}>
106 <div className="d-flex align-items-center justify-content-between">
107 <h2>{t('rounds.heading')}</h2>
108 {addRound && mayAddRounds(user, tournament) ?
109 <Button onClick={addRound}>
116 loadMore={moreRounds}
117 rounds={tournament.rounds}
118 tournament={tournament}
127 addRound: PropTypes.func,
128 moreRounds: PropTypes.func,
129 tournament: PropTypes.shape({
130 id: PropTypes.number,
131 participants: PropTypes.arrayOf(PropTypes.shape({
133 rounds: PropTypes.arrayOf(PropTypes.shape({
135 title: PropTypes.string,
139 export default Detail;