90 lines
2.3 KiB
Vue
90 lines
2.3 KiB
Vue
|
<!--
|
||
|
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
|
||
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
-->
|
||
|
<template>
|
||
|
<main>
|
||
|
<h1>Events</h1>
|
||
|
<label v-if="accountStore.valid">
|
||
|
Filter:
|
||
|
<select
|
||
|
v-model="filter"
|
||
|
>
|
||
|
<option
|
||
|
:value="undefined"
|
||
|
:selected="filter === undefined"
|
||
|
><All events></option>
|
||
|
<option
|
||
|
value="my-schedule"
|
||
|
:selected='filter === "my-schedule"'
|
||
|
>My Schedule</option>
|
||
|
<option
|
||
|
v-if="accountStore.isCrew"
|
||
|
value="assigned"
|
||
|
:selected='filter === "assigned"'
|
||
|
>Assigned to Me</option>
|
||
|
</select>
|
||
|
</label>
|
||
|
<CardEvent
|
||
|
v-for="event in events"
|
||
|
:key="`my-${event.id}`"
|
||
|
:id="String(event.name)"
|
||
|
:event
|
||
|
></CardEvent>
|
||
|
</main>
|
||
|
</template>
|
||
|
|
||
|
<script setup lang="ts">
|
||
|
useHead({
|
||
|
title: "Schedule",
|
||
|
});
|
||
|
|
||
|
const stringSort = useStringSort();
|
||
|
const events = computed(() => {
|
||
|
return [...schedule.value.events.values()].filter(e => !e.deleted && [...e.slots.values()].some(eventSlotFilter.value)).sort((a, b) => stringSort(a.name, b.name));
|
||
|
});
|
||
|
|
||
|
const accountStore = useAccountStore();
|
||
|
const usersStore = useUsersStore();
|
||
|
await usersStore.fetch();
|
||
|
const schedule = await useSchedule();
|
||
|
|
||
|
const route = useRoute();
|
||
|
const filter = computed({
|
||
|
get: () => queryToString(route.query.filter),
|
||
|
set: (value: string | undefined) => navigateTo({
|
||
|
path: route.path,
|
||
|
query: {
|
||
|
...route.query,
|
||
|
filter: value,
|
||
|
},
|
||
|
}),
|
||
|
});
|
||
|
|
||
|
const eventSlotFilter = computed(() => {
|
||
|
if (filter.value === undefined || !accountStore.valid || schedule.value.deleted) {
|
||
|
return () => true;
|
||
|
}
|
||
|
const aid = accountStore.id;
|
||
|
if (filter.value === "my-schedule") {
|
||
|
const slotIds = new Set(accountStore.interestedEventSlotIds);
|
||
|
for (const event of schedule.value.events.values()) {
|
||
|
if (!event.deleted && accountStore.interestedEventIds.has(event.id)) {
|
||
|
for (const slot of event.slots.values()) {
|
||
|
slotIds.add(slot.id);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return (slot: ClientScheduleEventSlot) => slotIds.has(slot.id) || slot.assigned.has(aid!) || false;
|
||
|
}
|
||
|
if (filter.value === "assigned") {
|
||
|
return (slot: ClientScheduleEventSlot) => slot.assigned.has(aid!) || false;
|
||
|
}
|
||
|
if (filter.value.startsWith("crew-")) {
|
||
|
const cid = parseInt(filter.value.slice(5));
|
||
|
return (slot: ClientScheduleEventSlot) => slot.assigned.has(cid) || false;
|
||
|
}
|
||
|
return () => false;
|
||
|
});
|
||
|
</script>
|