]> git.localhorst.tv Git - alttp.git/commitdiff
show some past episodes on concluded events
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 21 Oct 2023 16:34:38 +0000 (18:34 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 21 Oct 2023 16:34:38 +0000 (18:34 +0200)
app/Http/Controllers/EpisodeController.php
resources/js/components/events/Detail.js
resources/js/helpers/Event.js [new file with mode: 0644]
resources/js/i18n/de.js
resources/js/i18n/en.js
resources/js/pages/Event.js

index 785a24186f950e258a0dbe1afa851279e0412375..22ca6dc1309464c370325a41e92ea3f7e6906f77 100644 (file)
@@ -195,18 +195,28 @@ class EpisodeController extends Controller
                        'before' => 'nullable|date',
                        'event' => 'nullable|array',
                        'event.*' => 'numeric',
+                       'limit' => 'numeric',
+                       'offset' => 'numeric',
+                       'reverse' => 'boolean',
                ]);
-               $after = isset($validatedData['after']) ? $validatedData['after'] : Carbon::now();
                $before = isset($validatedData['before']) ? $validatedData['before'] : Carbon::now()->add(1, 'days');
+               $limit = isset($validatedData['limit']) ? $validatedData['limit'] : 100;
+               $reverse = isset($validatedData['reverse']) ? $validatedData['reverse'] : false;
                $episodes = Episode::with(['channels', 'event', 'players', 'players.user'])
                        ->select('episodes.*')
                        ->join('events', 'episodes.event_id', '=', 'events.id')
                        ->where('episodes.confirmed', '=', true)
-                       ->where(DB::raw('DATE_ADD(`episodes`.`start`, INTERVAL COALESCE(`episodes`.`estimate`, 0) SECOND)'), '>=', $after)
-                       ->where('episodes.start', '<=', $before)
                        ->where('events.visible', '=', true)
-                       ->orderBy('episodes.start')
+                       ->orderBy('episodes.start', $reverse ? 'DESC' : 'ASC')
                        ->limit(1000);
+               if (isset($validatedData['after'])) {
+                       $episodes = $episodes->where(
+                               DB::raw('DATE_ADD(`episodes`.`start`, INTERVAL COALESCE(`episodes`.`estimate`, 0) SECOND)'),
+                               '>=', $validatedData['after']);
+               }
+               if (isset($validatedData['before'])) {
+                       $episodes = $episodes->where('episodes.start', '<=', $validatedData['before']);
+               }
                if (!empty($validatedData['event'])) {
                        $episodes = $episodes->whereIn('episodes.event_id', $validatedData['event']);
                }
@@ -229,6 +239,7 @@ class EpisodeController extends Controller
                                'crew.user',
                        ]);
                }
+               $episodes->limit($limit);
                return $episodes->get()->toJson();
        }
 
index d530006b7800e48cf082a9d6c0483605e62712c3..65895482d320dd6b1ca07b740794e0435cc2b2ce 100644 (file)
@@ -1,10 +1,11 @@
 import PropTypes from 'prop-types';
 import React from 'react';
-import { Button } from 'react-bootstrap';
+import { Alert, Button } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 
 import Icon from '../common/Icon';
 import RawHTML from '../common/RawHTML';
+import { hasConcluded } from '../../helpers/Event';
 import { getTranslation } from '../../helpers/Technique';
 import i18n from '../../i18n';
 
@@ -32,6 +33,11 @@ const Detail = ({ actions, event }) => {
                {event.description ?
                        <RawHTML html={getTranslation(event.description, 'description', i18n.language)} />
                : null}
+               {hasConcluded(event) ?
+                       <Alert variant="info">
+                               {t('events.concluded')}
+                       </Alert>
+               : null}
        </>;
 };
 
@@ -42,6 +48,7 @@ Detail.propTypes = {
        event: PropTypes.shape({
                description: PropTypes.shape({
                }),
+               end: PropTypes.string,
                title: PropTypes.string,
        }),
 };
diff --git a/resources/js/helpers/Event.js b/resources/js/helpers/Event.js
new file mode 100644 (file)
index 0000000..da7a035
--- /dev/null
@@ -0,0 +1,3 @@
+import moment from 'moment';
+
+export const hasConcluded = event => event && event.end && moment(event.end).isBefore(moment());
index 79eb3716b65df2f58d75396b718a9a3f4193f943..7908d4f501cccd5742703e9a079675ab075483b7 100644 (file)
@@ -153,6 +153,8 @@ export default {
                        },
                },
                events: {
+                       concluded: 'Diese Veranstaltung is abgeschlossen.',
+                       pastEpisodes: 'Vergangene Rennen',
                        upcomingEpisodes: 'Anstehende Rennen',
                },
                footer: {
index 997c639d30158323fb19033f15eba50c14e42e22..417abf02ad7c4a50522b4ab492be0b4382f0cbfe 100644 (file)
@@ -153,6 +153,8 @@ export default {
                        },
                },
                events: {
+                       concluded: 'This event has concluded.',
+                       pastEpisodes: 'Past races',
                        upcomingEpisodes: 'Upcoming races',
                },
                footer: {
index 1a97cdc0700c808877eafa555cd6f6cb0b1a4804..c7f0ce55d228939ba93d5997cc019e38f517fbd4 100644 (file)
@@ -15,6 +15,7 @@ import Loading from '../components/common/Loading';
 import EpisodeList from '../components/episodes/List';
 import Detail from '../components/events/Detail';
 import Dialog from '../components/techniques/Dialog';
+import { hasConcluded } from '../helpers/Event';
 import {
        mayEditContent,
 } from '../helpers/permissions';
@@ -47,13 +48,19 @@ const Event = () => {
                        setEpisodes([]);
                        return;
                }
+               const params = {
+                       event: [event.id],
+               };
+               if (hasConcluded(event)) {
+                       params.limit = 25;
+                       params.reverse = '1';
+               } else {
+                       params.after = moment().subtract(3, 'hours').toISOString();
+                       params.before = moment().add(14, 'days').toISOString();
+               }
                axios.get(`/api/episodes`, {
                        signal: controller.signal,
-                       params: {
-                               after: moment().subtract(3, 'hours').toISOString(),
-                               before: moment().add(14, 'days').toISOString(),
-                               event: [event.id],
-                       },
+                       params,
                }).then(response => {
                        setEpisodes(response.data || []);
                }).catch(e => {
@@ -141,7 +148,12 @@ const Event = () => {
                <Container>
                        <Detail actions={actions} event={event} />
                        {episodes.length ? <>
-                               <h2 className="mt-4">{i18n.t('events.upcomingEpisodes')}</h2>
+                               <h2 className="mt-4">
+                                       {i18n.t(hasConcluded(event)
+                                               ? 'events.pastEpisodes'
+                                               : 'events.upcomingEpisodes'
+                                       )}
+                               </h2>
                                <EpisodeList episodes={episodes} />
                        </> : null}
                </Container>