owltide/pages/edit.vue
Hornwitser e722876aae
All checks were successful
/ build (push) Successful in 3m29s
/ deploy (push) Successful in 47s
Use a pinia store to manage account state
Refactor the existing scattered code dealing with the account state into
a pinia store.
2025-05-24 20:01:23 +02:00

129 lines
3.1 KiB
Vue

<template>
<main>
<h1>Edit</h1>
<label>
Crew Filter:
<select
v-model="crewFilter"
>
<option
:value="undefined"
:selected="crewFilter === undefined"
>&lt;All Crew&gt;</option>
<option
v-for="account in accounts?.filter(a => a.type === 'crew' || a.type === 'admin')"
:key="account.id"
:value="String(account.id)"
:selected="crewFilter === String(account.id)"
>{{ account.name }}</option>
</select>
</label>
<h2>Locations</h2>
<LocationsTable :edit="accountStore.canEditPublic" />
<h2>Schedule</h2>
<label>
Location Filter:
<select
v-model="locationFilter"
>
<option
:value="undefined"
:selected="locationFilter === undefined"
>&lt;All locations&gt;</option>
<option
v-for="location in schedule.locations"
:key="location.id"
:value="location.id"
:selected="locationFilter === location.id"
>{{ location.name }}</option>
</select>
</label>
<ScheduleTable :edit="true" :location="locationFilter" :eventSlotFilter :shiftSlotFilter />
<h2>Events</h2>
<EventsTable :edit="true" />
<h2>Roles</h2>
<RolesTable :edit="true" />
<h2>Shift Schedule</h2>
<label>
Role Filter:
<select
v-model="roleFilter"
>
<option
:value="undefined"
:selected="roleFilter === undefined"
>&lt;All roles&gt;</option>
<option
v-for="role in schedule.roles"
:key="role.id"
:value="role.id"
:selected="roleFilter === role.id"
>{{ role.name }}</option>
</select>
</label>
<ShiftScheduleTable :edit="true" :role="roleFilter" :eventSlotFilter :shiftSlotFilter />
<h2>Shifts</h2>
<ShiftsTable :edit="true" :role="roleFilter" />
</main>
</template>
<script lang="ts" setup>
import type { ShiftSlot, TimeSlot } from '~/shared/types/schedule';
definePageMeta({
middleware: ["authenticated"],
allowedAccountTypes: ["crew", "admin"],
});
const schedule = await useSchedule();
const { data: accounts } = await useAccounts();
const accountStore = useAccountStore();
const route = useRoute();
const crewFilter = computed({
get: () => queryToString(route.query.crew),
set: (value: string | undefined) => navigateTo({
path: route.path,
query: {
...route.query,
crew: value,
},
}),
});
const eventSlotFilter = computed(() => {
if (crewFilter.value === undefined || !accountStore.valid) {
return () => true;
}
const cid = parseInt(crewFilter.value);
return (slot: TimeSlot) => slot.assigned?.some(id => id === cid) || false;
});
const shiftSlotFilter = computed(() => {
if (crewFilter.value === undefined || !accountStore.valid) {
return () => true;
}
const cid = parseInt(crewFilter.value);
return (slot: ShiftSlot) => slot.assigned?.some(id => id === cid) || false;
});
const locationFilter = computed({
get: () => queryToString(route.query.location),
set: (value: string | undefined) => navigateTo({
path: route.path,
query: {
...route.query,
location: value,
},
}),
});
const roleFilter = computed({
get: () => queryToString(route.query.role),
set: (value: string | undefined) => navigateTo({
path: route.path,
query: {
...route.query,
role: value,
},
}),
});
</script>