]> git.localhorst.tv Git - alttp.git/blob - resources/js/pages/Tournament.js
offload some page chunks
[alttp.git] / resources / js / 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 '../components/common/CanonicalLinks';
7 import ErrorBoundary from '../components/common/ErrorBoundary';
8 import ErrorMessage from '../components/common/ErrorMessage';
9 import Loading from '../components/common/Loading';
10 import NotFound from '../pages/NotFound';
11 import Detail from '../components/tournament/Detail';
12 import {
13         patchApplication,
14         patchParticipant,
15         patchResult,
16         patchRound,
17         patchUser,
18         removeApplication,
19         sortParticipants,
20 } from '../helpers/Tournament';
21
22 export const Component = () => {
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                                 if (e.participant) {
69                                         setTournament(tournament => patchParticipant(tournament, e.participant));
70                                 }
71                         })
72                         .listen('ResultChanged', e => {
73                                 if (e.result) {
74                                         setTournament(tournament => patchResult(tournament, e.result));
75                                 }
76                         })
77                         .listen('RoundAdded', e => {
78                                 if (e.round) {
79                                         setTournament(tournament => ({
80                                                 ...tournament,
81                                                 rounds: [e.round, ...tournament.rounds],
82                                         }));
83                                 }
84                         })
85                         .listen('RoundChanged', e => {
86                                 if (e.round) {
87                                         setTournament(tournament => patchRound(tournament, e.round));
88                                 }
89                         })
90                         .listen('TournamentChanged', e => {
91                                 if (e.tournament) {
92                                         setTournament(tournament => ({ ...tournament, ...e.tournament }));
93                                 }
94                         });
95                 return () => {
96                         window.Echo.leave(`Tournament.${id}`);
97                 };
98         }, [id]);
99
100         useEffect(() => {
101                 const cb = (e) => {
102                         if (e.user) {
103                                 setTournament(tournament => patchUser(tournament, e.user));
104                         }
105                 };
106                 window.Echo.channel('App.Control')
107                         .listen('UserChanged', cb);
108                 return () => {
109                         window.Echo.channel('App.Control')
110                                 .stopListening('UserChanged', cb);
111                 };
112         }, []);
113
114         if (loading) {
115                 return <Loading />;
116         }
117
118         if (error) {
119                 return <ErrorMessage error={error} />;
120         }
121
122         if (!tournament) {
123                 return <NotFound />;
124         }
125
126         const addRound = async () => {
127                 await axios.post('/api/rounds', { tournament_id: tournament.id });
128         };
129
130         return <ErrorBoundary>
131                 <Helmet>
132                         <title>{tournament.title}</title>
133                 </Helmet>
134                 <CanonicalLinks base={`/tournaments/${tournament.id}`} />
135                 <Detail addRound={addRound} tournament={tournament} />
136         </ErrorBoundary>;
137 };