]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/tournament/Detail.js
tournament admin control
[alttp.git] / resources / js / components / tournament / Detail.js
1 import PropTypes from 'prop-types';
2 import React from 'react';
3 import { Button, Col, Container, Row } from 'react-bootstrap';
4 import { withTranslation } from 'react-i18next';
5
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';
14 import {
15         isRunner,
16         mayAddRounds,
17         mayUpdateTournament,
18         mayViewProtocol,
19 } from '../../helpers/permissions';
20 import {
21         getTournamentAdmins,
22         getTournamentMonitors,
23         hasRunners,
24         hasTournamentAdmins,
25         hasTournamentMonitors,
26 } from '../../helpers/Tournament';
27 import { withUser } from '../../helpers/UserContext';
28 import i18n from '../../i18n';
29
30 const getClassName = (tournament, user) => {
31         const classNames = ['tournament'];
32         if (tournament.locked) {
33                 classNames.push('is-locked');
34         } else {
35                 classNames.push('is-active');
36         }
37         if (isRunner(user, tournament)) {
38                 classNames.push('is-runner');
39         }
40         return classNames.join(' ');
41 };
42
43 const Detail = ({
44         addRound,
45         tournament,
46         user,
47 }) => <Container className={getClassName(tournament, user)} fluid>
48         <Row>
49                 <Col lg={8} xl={9}>
50                         <div className="d-flex align-items-center justify-content-between">
51                                 <h1>{tournament.title}</h1>
52                                 <div className="button-bar">
53                                         <ApplicationsButton tournament={tournament} />
54                                         <ApplyButton tournament={tournament} />
55                                         {mayUpdateTournament(user, tournament) ?
56                                                 <SettingsButton tournament={tournament} />
57                                         : null}
58                                         {mayViewProtocol(user, tournament) ?
59                                                 <Protocol id={tournament.id} />
60                                         : null}
61                                 </div>
62                         </div>
63                 </Col>
64         </Row>
65         <Row>
66                 <Col lg={{ order: 2, span: 4 }} xl={{ order: 2, span: 3 }}>
67                         <div className="tournament-sidebar">
68                                 <div className="d-flex align-items-center justify-content-between">
69                                         <h2>{i18n.t('tournaments.scoreboard')}</h2>
70                                         {hasRunners(tournament) && tournament.rounds.length > 2 ?
71                                                 <ScoreChartButton tournament={tournament} />
72                                         : null}
73                                 </div>
74                                 {hasRunners(tournament) ?
75                                         <Scoreboard tournament={tournament} />
76                                 : null}
77                                 {hasTournamentAdmins(tournament) ?
78                                         <>
79                                                 <div className="d-flex align-items-center justify-content-between">
80                                                         <h2>{i18n.t('tournaments.admins')}</h2>
81                                                 </div>
82                                                 {getTournamentAdmins(tournament).map(p =>
83                                                         <p key={p.id}><Box user={p.user} /></p>
84                                                 )}
85                                         </>
86                                 : null}
87                                 {hasTournamentMonitors(tournament) ?
88                                         <>
89                                                 <div className="d-flex align-items-center justify-content-between">
90                                                         <h2>{i18n.t('tournaments.monitors')}</h2>
91                                                 </div>
92                                                 {getTournamentMonitors(tournament).map(p =>
93                                                         <p key={p.id}><Box user={p.user} /></p>
94                                                 )}
95                                         </>
96                                 : null}
97                         </div>
98                 </Col>
99                 <Col lg={{ order: 1, span: 8 }} xl={{ order: 1, span: 9 }}>
100                         <div className="d-flex align-items-center justify-content-between">
101                                 <h2>{i18n.t('rounds.heading')}</h2>
102                                 {addRound && mayAddRounds(user, tournament) ?
103                                         <Button onClick={addRound}>
104                                                 {i18n.t('rounds.new')}
105                                         </Button>
106                                 : null}
107                         </div>
108                         {tournament.rounds ?
109                                 <Rounds rounds={tournament.rounds} tournament={tournament} />
110                         : null}
111                 </Col>
112         </Row>
113 </Container>;
114
115 Detail.propTypes = {
116         addRound: PropTypes.func,
117         tournament: PropTypes.shape({
118                 id: PropTypes.number,
119                 participants: PropTypes.arrayOf(PropTypes.shape({
120                 })),
121                 rounds: PropTypes.arrayOf(PropTypes.shape({
122                 })),
123                 title: PropTypes.string,
124         }),
125         user: PropTypes.shape({
126         }),
127 };
128
129 export default withTranslation()(withUser(Detail));