Use a pinia store to manage account state
Refactor the existing scattered code dealing with the account state into a pinia store.
This commit is contained in:
parent
fae8b4e2e4
commit
e722876aae
12 changed files with 126 additions and 98 deletions
|
@ -5,13 +5,13 @@
|
|||
<p v-if="event.interested">
|
||||
{{ event.interested }} interested
|
||||
</p>
|
||||
<p v-if="sessionStore.account">
|
||||
<p v-if="accountStore.interestedIds">
|
||||
<button
|
||||
class="interested"
|
||||
:class="{ active: interestedIds.has(event.id) }"
|
||||
:class="{ active: accountStore.interestedIds?.has(event.id) }"
|
||||
@click="toggle(event.id, event.slots.map(slot => slot.id))"
|
||||
>
|
||||
{{ interestedIds.has(event.id) ? "✔ interested" : "🔔 interested?" }}
|
||||
{{ accountStore.interestedIds?.has(event.id) ? "✔ interested" : "🔔 interested?" }}
|
||||
</button>
|
||||
</p>
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
|||
<li v-for="slot in event.slots" :key="slot.id">
|
||||
{{ formatTime(slot.start) }} - {{ formatTime(slot.end) }}
|
||||
<button
|
||||
v-if="sessionStore.account && event.slots.length > 1"
|
||||
v-if="accountStore.interestedIds && event.slots.length > 1"
|
||||
class="interested"
|
||||
:disabled="interestedIds.has(event.id)"
|
||||
:class="{ active: interestedIds.has(event.id) || interestedIds.has(slot.id) }"
|
||||
:disabled="accountStore.interestedIds.has(event.id)"
|
||||
:class="{ active: accountStore.interestedIds.has(event.id) || accountStore.interestedIds.has(slot.id) }"
|
||||
@click="toggle(slot.id)"
|
||||
>
|
||||
{{ interestedIds.has(event.id) || interestedIds.has(slot.id) ? "✔ interested" : "🔔 interested?" }}
|
||||
{{ accountStore.interestedIds.has(event.id) || accountStore.interestedIds.has(slot.id) ? "✔ interested" : "🔔 interested?" }}
|
||||
</button>
|
||||
<template v-if="slot.interested">
|
||||
({{ slot.interested }} interested)
|
||||
|
@ -48,33 +48,16 @@ defineProps<{
|
|||
event: ScheduleEvent
|
||||
}>()
|
||||
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const sessionStore = useSessionStore();
|
||||
const interestedIds = computed(() => new Set(sessionStore.account?.interestedIds ?? []));
|
||||
const timezone = computed(() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone);
|
||||
const accountStore = useAccountStore();
|
||||
const { data: accounts } = await useAccounts();
|
||||
const idToAccount = computed(() => new Map(accounts.value?.map(a => [a.id, a])));
|
||||
|
||||
function formatTime(time: string) {
|
||||
return DateTime.fromISO(time, { zone: timezone.value }).toFormat("yyyy-LL-dd HH:mm");
|
||||
return DateTime.fromISO(time, { zone: accountStore.activeTimezone }).toFormat("yyyy-LL-dd HH:mm");
|
||||
}
|
||||
|
||||
async function toggle(id: string, slotIds?: string[]) {
|
||||
let newIds = [...sessionStore.account!.interestedIds ?? []];
|
||||
if (interestedIds.value.has(id)) {
|
||||
newIds = newIds.filter(newId => newId !== id);
|
||||
} else {
|
||||
newIds.push(id);
|
||||
if (slotIds) {
|
||||
const filterIds = new Set(slotIds);
|
||||
newIds = newIds.filter(newId => !filterIds.has(newId));
|
||||
}
|
||||
}
|
||||
await $fetch("/api/account", {
|
||||
method: "PATCH",
|
||||
body: { interestedIds: newIds },
|
||||
})
|
||||
await sessionStore.fetch();
|
||||
await accountStore.toggleInterestedId(id, slotIds);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
:disabled="!canEditPublic"
|
||||
:disabled="!accountStore.canEditPublic"
|
||||
:value="!event.crew"
|
||||
:checked="!event.crew"
|
||||
@change="editEvent(event, { crew: !($event as any).target.value })"
|
||||
|
@ -75,7 +75,7 @@
|
|||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
:disabled="!canEditPublic"
|
||||
:disabled="!accountStore.canEditPublic"
|
||||
v-model="newEventPublic"
|
||||
>
|
||||
</td>
|
||||
|
@ -135,11 +135,10 @@ defineProps<{
|
|||
}>();
|
||||
|
||||
const schedule = await useSchedule();
|
||||
const sessionStore = useSessionStore();
|
||||
const canEditPublic = computed(() => sessionStore.account?.type === "admin");
|
||||
const accountStore = useAccountStore();
|
||||
|
||||
function canEdit(event: ScheduleEvent) {
|
||||
return event.crew || canEditPublic.value;
|
||||
return event.crew || accountStore.canEditPublic;
|
||||
}
|
||||
|
||||
const changes = ref<ChangeRecord<ScheduleEvent>[]>([]);
|
||||
|
|
|
@ -8,18 +8,18 @@
|
|||
<li>
|
||||
<NuxtLink to="/schedule">Schedule</NuxtLink>
|
||||
</li>
|
||||
<li v-if="sessionStore.account?.type === 'admin' || sessionStore.account?.type === 'crew'">
|
||||
<li v-if="accountStore.canEdit">
|
||||
<NuxtLink to="/edit">Edit</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="account">
|
||||
<template v-if="sessionStore.account">
|
||||
{{ sessionStore.account.name }}
|
||||
(s:{{ sessionStore.id }} a:{{ sessionStore.account.id }}{{ sessionStore.push ? " push" : null }})
|
||||
{{ sessionStore.account.type }}
|
||||
<template v-if="accountStore.valid">
|
||||
{{ accountStore.name }}
|
||||
(s:{{ sessionStore.id }} a:{{ accountStore.id }}{{ sessionStore.push ? " push" : null }})
|
||||
{{ accountStore.type }}
|
||||
<NuxtLink to="/account/settings">Settings</NuxtLink>
|
||||
<LogOutButton v-if="sessionStore.account.type !== 'anonymous'"/>
|
||||
<LogOutButton v-if="accountStore.type !== 'anonymous'"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<NuxtLink to="/login">Log In</NuxtLink>
|
||||
|
@ -29,6 +29,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const accountStore = useAccountStore();
|
||||
const sessionStore = useSessionStore();
|
||||
</script>
|
||||
|
||||
|
|
|
@ -424,12 +424,8 @@ function removeSlot(eventChanges: ChangeRecord<ScheduleEvent>[], event: Schedule
|
|||
return eventChanges;
|
||||
}
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
const accountStore = useAccountStore();
|
||||
const schedule = await useSchedule();
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const timezone = computed(
|
||||
() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone
|
||||
);
|
||||
|
||||
type EventSlotChange = { op: "set" | "del", data: EventSlot } ;
|
||||
|
||||
|
@ -466,12 +462,12 @@ const newEventStart = ref("");
|
|||
const newEventDuration = ref("01:00");
|
||||
const newEventEnd = computed({
|
||||
get: () => (
|
||||
DateTime.fromISO(newEventStart.value, { zone: timezone.value })
|
||||
DateTime.fromISO(newEventStart.value, { zone: accountStore.activeTimezone })
|
||||
.plus(Duration.fromISOTime(newEventDuration.value))
|
||||
.toFormat("HH:mm")
|
||||
),
|
||||
set: (value: string) => {
|
||||
const start = DateTime.fromISO(newEventStart.value, { zone: timezone.value });
|
||||
const start = DateTime.fromISO(newEventStart.value, { zone: accountStore.activeTimezone });
|
||||
const end = endFromTime(start, value);
|
||||
newEventDuration.value = dropDay(end.diff(start)).toFormat("hh:mm");
|
||||
},
|
||||
|
@ -508,7 +504,7 @@ function editEventSlot(
|
|||
}
|
||||
) {
|
||||
if (edits.start) {
|
||||
const start = DateTime.fromISO(edits.start, { zone: timezone.value });
|
||||
const start = DateTime.fromISO(edits.start, { zone: accountStore.activeTimezone });
|
||||
eventSlot = {
|
||||
...eventSlot,
|
||||
start,
|
||||
|
@ -577,7 +573,7 @@ function newEventSlot(options: { start?: DateTime, end?: DateTime } = {}) {
|
|||
end = options.end;
|
||||
start = options.end.minus(duration);
|
||||
} else {
|
||||
start = DateTime.fromISO(newEventStart.value, { zone: timezone.value });
|
||||
start = DateTime.fromISO(newEventStart.value, { zone: accountStore.activeTimezone });
|
||||
end = endFromTime(start, newEventEnd.value);
|
||||
}
|
||||
if (!start.isValid || !end.isValid) {
|
||||
|
@ -641,8 +637,8 @@ const eventSlots = computed(() => {
|
|||
location,
|
||||
assigned: slot.assigned ?? [],
|
||||
origLocation: location,
|
||||
start: DateTime.fromISO(slot.start, { zone: timezone.value }),
|
||||
end: DateTime.fromISO(slot.end, { zone: timezone.value }),
|
||||
start: DateTime.fromISO(slot.start, { zone: accountStore.activeTimezone }),
|
||||
end: DateTime.fromISO(slot.end, { zone: accountStore.activeTimezone }),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,12 +394,8 @@ function removeSlot(eventChanges: ChangeRecord<Shift>[], shift: Shift, shiftSlot
|
|||
return eventChanges;
|
||||
}
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
const accountStore = useAccountStore();
|
||||
const schedule = await useSchedule();
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const timezone = computed(
|
||||
() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone
|
||||
);
|
||||
|
||||
type ShiftSlotChange = { op: "set" | "del", data: ShiftSlot } ;
|
||||
|
||||
|
@ -436,12 +432,12 @@ const newShiftStart = ref("");
|
|||
const newShiftDuration = ref("01:00");
|
||||
const newShiftEnd = computed({
|
||||
get: () => (
|
||||
DateTime.fromISO(newShiftStart.value, { zone: timezone.value })
|
||||
DateTime.fromISO(newShiftStart.value, { zone: accountStore.activeTimezone })
|
||||
.plus(Duration.fromISOTime(newShiftDuration.value))
|
||||
.toFormat("HH:mm")
|
||||
),
|
||||
set: (value: string) => {
|
||||
const start = DateTime.fromISO(newShiftStart.value, { zone: timezone.value });
|
||||
const start = DateTime.fromISO(newShiftStart.value, { zone: accountStore.activeTimezone });
|
||||
const end = endFromTime(start, value);
|
||||
newShiftDuration.value = dropDay(end.diff(start)).toFormat("hh:mm");
|
||||
},
|
||||
|
@ -478,7 +474,7 @@ function editShiftSlot(
|
|||
}
|
||||
) {
|
||||
if (edits.start) {
|
||||
const start = DateTime.fromISO(edits.start, { zone: timezone.value });
|
||||
const start = DateTime.fromISO(edits.start, { zone: accountStore.activeTimezone });
|
||||
shiftSlot = {
|
||||
...shiftSlot,
|
||||
start,
|
||||
|
@ -558,7 +554,7 @@ function newShiftSlot(options: { start?: DateTime, end?: DateTime } = {}) {
|
|||
end = options.end;
|
||||
start = options.end.minus(duration);
|
||||
} else {
|
||||
start = DateTime.fromISO(newShiftStart.value, { zone: timezone.value });
|
||||
start = DateTime.fromISO(newShiftStart.value, { zone: accountStore.activeTimezone });
|
||||
end = endFromTime(start, newShiftEnd.value);
|
||||
}
|
||||
if (!start.isValid || !end.isValid) {
|
||||
|
@ -621,8 +617,8 @@ const shiftSlots = computed(() => {
|
|||
role: shift.role,
|
||||
assigned: slot.assigned ?? [],
|
||||
origRole: shift.role,
|
||||
start: DateTime.fromISO(slot.start, { zone: timezone.value }),
|
||||
end: DateTime.fromISO(slot.end, { zone: timezone.value }),
|
||||
start: DateTime.fromISO(slot.start, { zone: accountStore.activeTimezone }),
|
||||
end: DateTime.fromISO(slot.end, { zone: accountStore.activeTimezone }),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,16 +503,14 @@ const stretches = computed(() => [
|
|||
)
|
||||
])
|
||||
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const sessionStore = useSessionStore();
|
||||
const debugTimezone = ref<undefined | string>();
|
||||
const accountStore = useAccountStore();
|
||||
const timezone = computed({
|
||||
get: () => debugTimezone.value ?? sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone,
|
||||
set: (value: string) => { debugTimezone.value = value },
|
||||
get: () => accountStore.activeTimezone,
|
||||
set: (value: string) => { accountStore.timezone = value },
|
||||
});
|
||||
|
||||
const elements = computed(() => tableElementsFromStretches(
|
||||
stretches.value, schedule.value.events, schedule.value.locations, schedule.value.rota, schedule.value.roles, timezone.value
|
||||
stretches.value, schedule.value.events, schedule.value.locations, schedule.value.rota, schedule.value.roles, accountStore.activeTimezone
|
||||
));
|
||||
const totalColumns = computed(() => elements.value.totalColumns);
|
||||
const columnGroups = computed(() => elements.value.columnGroups);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue