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