Separate event dipslay from event slot display

Pull out the list of events into its own page sorted by name and show
the event slots in chronological order on the schedule page, with past
slots hidden by default.  This makes the content underneath the schedule
the most immediately useful to have in the moment, while the full list
is kept separately and in a predictable order.
This commit is contained in:
Hornwitser 2025-07-16 19:37:23 +02:00
parent 848a330f3a
commit ae1c653af6
5 changed files with 198 additions and 5 deletions

View file

@ -4,7 +4,7 @@
-->
<template>
<main>
<h1>Schedule & Events</h1>
<h1>Schedule</h1>
<p>
Study carefully, we only hold these events once a year.
</p>
@ -46,10 +46,15 @@
</label>
<Timetable :schedule :eventSlotFilter :shiftSlotFilter />
<h2>Events</h2>
<CardEvent
v-for="event in [...schedule.events.values()].filter(e => !e.deleted && [...e.slots.values()].some(eventSlotFilter))"
:key="event.id"
:event
<label>
Hide past events
<input type="checkbox" v-model="hidePastEvents">
</label>
<CardEventSlot
v-for="eventSlot in eventSlots"
:key="eventSlot.slot.id"
:event="eventSlot.event"
:slot="eventSlot.slot"
/>
<template v-if="accountStore.isCrew">
<h2>Shifts</h2>
@ -91,6 +96,17 @@ const filter = computed({
}),
});
const hidePastEvents = computed({
get: () => !queryToBoolean(route.query.showPast),
set: (value: boolean) => navigateTo({
path: route.path,
query: {
...route.query,
showPast: value ? undefined : null,
},
}),
});
const eventSlotFilter = computed(() => {
if (filter.value === undefined || !accountStore.valid || schedule.value.deleted) {
return () => true;
@ -130,4 +146,15 @@ const shiftSlotFilter = computed(() => {
}
return () => false;
});
const eventSlots = computed(() => {
let slots = [...schedule.value.eventSlots.values()].filter(slot => !slot.deleted && eventSlotFilter.value(slot));
if (hidePastEvents.value) {
const nowMs = Date.now();
slots = slots.filter(slot => slot.end.toMillis() >= nowMs);
}
slots.sort((a, b) => a.start.toMillis() - b.start.toMillis() || a.end.toMillis() - b.end.toMillis());
return slots.map(slot => ({ slot, event: schedule.value.events.get(slot.eventId!) }));
});
</script>