]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/pages/Tournament.js
more alternate/canonical links
[alttp.git] / resources / js / components / pages / Tournament.js
1 import axios from 'axios';
2 import React, { useEffect, useState } from 'react';
3 import { Helmet } from 'react-helmet';
4 import { useParams } from 'react-router-dom';
5
6 import CanonicalLinks from '../common/CanonicalLinks';
7 import ErrorBoundary from '../common/ErrorBoundary';
8 import ErrorMessage from '../common/ErrorMessage';
9 import Loading from '../common/Loading';
10 import NotFound from '../pages/NotFound';
11 import Detail from '../tournament/Detail';
12 import {
13         patchApplication,
14         patchParticipant,
15         patchResult,
16         patchRound,
17         patchUser,
18         removeApplication,
19         sortParticipants,
20 } from '../../helpers/Tournament';
21
22 const Tournament = () => {
23         const params = useParams();
24         const { id } = params;
25
26         const [error, setError] = useState(null);
27         const [loading, setLoading] = useState(true);
28         const [tournament, setTournament] = useState(null);
29
30         useEffect(() => {
31                 const ctrl = new AbortController();
32                 setLoading(true);
33                 axios
34                         .get(`/api/tournaments/${id}`, { signal: ctrl.signal })
35                         .then(response => {
36                                 setError(null);
37                                 setLoading(false);
38                                 setTournament(sortParticipants(response.data));
39                         })
40                         .catch(error => {
41                                 setError(error);
42                                 setLoading(false);
43                                 setTournament(null);
44                         });
45                 return () => {
46                         ctrl.abort();
47                 };
48         }, [id]);
49
50         useEffect(() => {
51                 window.Echo.channel(`Tournament.${id}`)
52                         .listen('ApplicationAdded', e => {
53                                 if (e.application) {
54                                         setTournament(tournament => patchApplication(tournament, e.application));
55                                 }
56                         })
57                         .listen('ApplicationChanged', e => {
58                                 if (e.application) {
59                                         setTournament(tournament => patchApplication(tournament, e.application));
60                                 }
61                         })
62                         .listen('ApplicationRemoved', e => {
63                                 if (e.application_id) {
64                                         setTournament(tournament => removeApplication(tournament, e.application_id));
65                                 }
66                         })
67                         .listen('ParticipantChanged', e => {
68                                 console.log(e);
69                                 if (e.participant) {
70                                         setTournament(tournament => patchParticipant(tournament, e.participant));
71                                 }
72                         })
73                         .listen('ResultChanged', e => {
74                                 if (e.result) {
75                                         setTournament(tournament => patchResult(tournament, e.result));
76                                 }
77                         })
78                         .listen('RoundAdded', e => {
79                                 if (e.round) {
80                                         setTournament(tournament => ({
81                                                 ...tournament,
82                                                 rounds: [e.round, ...tournament.rounds],
83                                         }));
84                                 }
85                         })
86                         .listen('RoundChanged', e => {
87                                 if (e.round) {
88                                         setTournament(tournament => patchRound(tournament, e.round));
89                                 }
90                         })
91                         .listen('TournamentChanged', e => {
92                                 if (e.tournament) {
93                                         setTournament(tournament => ({ ...tournament, ...e.tournament }));
94                                 }
95                         });
96                 return () => {
97                         window.Echo.leave(`Tournament.${id}`);
98                 };
99         }, [id]);
100
101         useEffect(() => {
102                 const cb = (e) => {
103                         if (e.user) {
104                                 setTournament(tournament => patchUser(tournament, e.user));
105                         }
106                 };
107                 window.Echo.channel('App.Control')
108                         .listen('UserChanged', cb);
109                 return () => {
110                         window.Echo.channel('App.Control')
111                                 .stopListening('UserChanged', cb);
112                 };
113         }, []);
114
115         if (loading) {
116                 return <Loading />;
117         }
118
119         if (error) {
120                 return <ErrorMessage error={error} />;
121         }
122
123         if (!tournament) {
124                 return <NotFound />;
125         }
126
127         const addRound = async () => {
128                 await axios.post('/api/rounds', { tournament_id: tournament.id });
129         };
130
131         return <ErrorBoundary>
132                 <Helmet>
133                         <title>{tournament.title}</title>
134                 </Helmet>
135                 <CanonicalLinks base={`/tournaments/${tournament.id}`} />
136                 <Detail addRound={addRound} tournament={tournament} />
137         </ErrorBoundary>;
138 };
139
140 export default Tournament;