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';
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';
14 export const Component = () => {
15 const { t } = useTranslation();
17 const [error, setError] = React.useState(null);
18 const [loading, setLoading] = React.useState(true);
19 const [events, setEvents] = React.useState([]);
21 const fetchEvents = React.useCallback(async (controller) => {
24 with: ['description'],
27 const response = await axios.get(`/api/events`, {
28 signal: controller.signal,
31 return response.data || [];
33 if (!axios.isCancel(error)) {
40 React.useEffect(() => {
41 const controller = new AbortController();
43 fetchEvents(controller)
59 const evergreen = React.useMemo(() =>
60 events.filter(isEvergreen)
62 const ongoing = React.useMemo(() =>
63 events.filter(isOngoing).sort((a, b) => compareStart(a, b) * -1)
65 const past = React.useMemo(() =>
66 events.filter(hasConcluded)
74 return <ErrorMessage error={error} />;
77 return <ErrorBoundary>
83 <CanonicalLinks base={`/events`} />
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} />