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