]> git.localhorst.tv Git - alttp.git/blob - resources/js/pages/Events.js
add known bot
[alttp.git] / resources / js / pages / Events.js
1 import axios from 'axios';
2 import React from 'react';
3 import { Container } from 'react-bootstrap';
4 import { Helmet } from 'react-helmet';
5 import { useTranslation } from 'react-i18next';
6
7 import CanonicalLinks from '../components/common/CanonicalLinks';
8 import ErrorBoundary from '../components/common/ErrorBoundary';
9 import ErrorMessage from '../components/common/ErrorMessage';
10 import Loading from '../components/common/Loading';
11 import List from '../components/events/List';
12 import { compareStart, hasConcluded, isEvergreen, isOngoing } from '../helpers/Event';
13
14 export const Component = () => {
15         const { t } = useTranslation();
16
17         const [error, setError] = React.useState(null);
18         const [loading, setLoading] = React.useState(true);
19         const [events, setEvents] = React.useState([]);
20
21         const fetchEvents = React.useCallback(async (controller) => {
22                 const params = {
23                         order: 'recency',
24                         with: ['description'],
25                 };
26                 try {
27                         const response = await axios.get(`/api/events`, {
28                                 signal: controller.signal,
29                                 params,
30                         });
31                         return response.data || [];
32                 } catch (error) {
33                         if (!axios.isCancel(error)) {
34                                 throw error;
35                         }
36                         return [];
37                 }
38         }, []);
39
40         React.useEffect(() => {
41                 const controller = new AbortController();
42                 setLoading(true);
43                 fetchEvents(controller)
44                         .then(events => {
45                                 setError(null);
46                                 setLoading(false);
47                                 setEvents(events);
48                         })
49                         .catch(error => {
50                                 setError(error);
51                                 setLoading(false);
52                                 setEvents([]);
53                         });
54                 return () => {
55                         controller.abort();
56                 };
57         }, [fetchEvents]);
58
59         const evergreen = React.useMemo(() =>
60                 events.filter(isEvergreen)
61         , [events]);
62         const ongoing = React.useMemo(() =>
63                 events.filter(isOngoing).sort((a, b) => compareStart(a, b) * -1)
64         , [events]);
65         const past = React.useMemo(() =>
66                 events.filter(hasConcluded)
67         , [events]);
68
69         if (loading) {
70                 return <Loading />;
71         }
72
73         if (error) {
74                 return <ErrorMessage error={error} />;
75         }
76
77         return <ErrorBoundary>
78                 <Helmet>
79                         <title>
80                                 {t('events.heading')}
81                         </title>
82                 </Helmet>
83                 <CanonicalLinks base={`/events`} />
84                 <Container>
85                         <h1>{t('events.ongoing')}</h1>
86                         <List events={ongoing} />
87                         <h1>{t('events.evergreen')}</h1>
88                         <List events={evergreen} />
89                         <h1>{t('events.past')}</h1>
90                         <List events={past} />
91                 </Container>
92         </ErrorBoundary>;
93 };