Use a pinia store to manage session state

Replace the convoluted useAccountSession composable with a pinia store
that in addition allows for the consolidation of all session related
functions to grouped into one module.
This commit is contained in:
Hornwitser 2025-05-24 17:53:33 +02:00
parent c47452a8b4
commit fae8b4e2e4
21 changed files with 181 additions and 118 deletions

View file

@ -5,7 +5,7 @@
<p v-if="event.interested">
{{ event.interested }} interested
</p>
<p v-if="session">
<p v-if="sessionStore.account">
<button
class="interested"
:class="{ active: interestedIds.has(event.id) }"
@ -20,7 +20,7 @@
<li v-for="slot in event.slots" :key="slot.id">
{{ formatTime(slot.start) }} - {{ formatTime(slot.end) }}
<button
v-if="session && event.slots.length > 1"
v-if="sessionStore.account && event.slots.length > 1"
class="interested"
:disabled="interestedIds.has(event.id)"
:class="{ active: interestedIds.has(event.id) || interestedIds.has(slot.id) }"
@ -49,9 +49,9 @@ defineProps<{
}>()
const runtimeConfig = useRuntimeConfig();
const { data: session, refresh: refreshSession } = await useAccountSession();
const interestedIds = computed(() => new Set(session.value?.account.interestedIds ?? []));
const timezone = computed(() => session.value?.account?.timezone ?? runtimeConfig.public.defaultTimezone);
const sessionStore = useSessionStore();
const interestedIds = computed(() => new Set(sessionStore.account?.interestedIds ?? []));
const timezone = computed(() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone);
const { data: accounts } = await useAccounts();
const idToAccount = computed(() => new Map(accounts.value?.map(a => [a.id, a])));
@ -60,7 +60,7 @@ function formatTime(time: string) {
}
async function toggle(id: string, slotIds?: string[]) {
let newIds = [...session.value!.account.interestedIds ?? []];
let newIds = [...sessionStore.account!.interestedIds ?? []];
if (interestedIds.value.has(id)) {
newIds = newIds.filter(newId => newId !== id);
} else {
@ -74,7 +74,7 @@ async function toggle(id: string, slotIds?: string[]) {
method: "PATCH",
body: { interestedIds: newIds },
})
await refreshSession();
await sessionStore.fetch();
}
</script>

View file

@ -135,8 +135,8 @@ defineProps<{
}>();
const schedule = await useSchedule();
const { data: session } = await useAccountSession();
const canEditPublic = computed(() => session.value?.account.type === "admin");
const sessionStore = useSessionStore();
const canEditPublic = computed(() => sessionStore.account?.type === "admin");
function canEdit(event: ScheduleEvent) {
return event.crew || canEditPublic.value;

View file

@ -8,18 +8,18 @@
<li>
<NuxtLink to="/schedule">Schedule</NuxtLink>
</li>
<li v-if="session?.account?.type === 'admin' || session?.account?.type === 'crew'">
<li v-if="sessionStore.account?.type === 'admin' || sessionStore.account?.type === 'crew'">
<NuxtLink to="/edit">Edit</NuxtLink>
</li>
</ul>
</nav>
<div class="account">
<template v-if="session?.account">
{{ session.account.name }}
(s:{{ session.id }} a:{{ session.account.id }}{{ session.push ? " push" : null }})
{{ session.account.type }}
<template v-if="sessionStore.account">
{{ sessionStore.account.name }}
(s:{{ sessionStore.id }} a:{{ sessionStore.account.id }}{{ sessionStore.push ? " push" : null }})
{{ sessionStore.account.type }}
<NuxtLink to="/account/settings">Settings</NuxtLink>
<LogOutButton v-if="session.account.type !== 'anonymous'"/>
<LogOutButton v-if="sessionStore.account.type !== 'anonymous'"/>
</template>
<template v-else>
<NuxtLink to="/login">Log In</NuxtLink>
@ -29,7 +29,7 @@
</template>
<script lang="ts" setup>
const { data: session } = await useAccountSession();
const sessionStore = useSessionStore();
</script>
<style scoped>

View file

@ -1,19 +1,7 @@
<template>
<button type="button" @click="logOut">Log out</button>
<button type="button" @click="sessionStore.logOut">Log out</button>
</template>
<script setup lang="ts">
const { refresh: sessionRefresh } = useAccountSession();
async function logOut() {
try {
await $fetch.raw("/api/auth/session", {
method: "DELETE",
});
await sessionRefresh();
} catch (err: any) {
alert(`Log out failed: ${err.statusCode} ${err.statusMessage}`);
}
}
const sessionStore = useSessionStore();
</script>

View file

@ -18,15 +18,15 @@
</template>
<script setup lang="ts">
const { data: session, refresh: refreshSession } = await useAccountSession();
const sessionStore = useSessionStore();
const { supported, subscription, getSubscription, subscribe, unsubscribe } = usePushNotification();
const subscribed = computed(() => Boolean(subscription.value && session.value?.push))
const subscribed = computed(() => Boolean(subscription.value && sessionStore.push));
async function onClick() {
if (!subscribed.value)
await subscribe();
else
await unsubscribe();
await refreshSession();
await sessionStore.fetch();
}
onMounted(() => {

View file

@ -424,11 +424,11 @@ function removeSlot(eventChanges: ChangeRecord<ScheduleEvent>[], event: Schedule
return eventChanges;
}
const { data: session } = await useAccountSession();
const sessionStore = useSessionStore();
const schedule = await useSchedule();
const runtimeConfig = useRuntimeConfig();
const timezone = computed(
() => session.value?.account?.timezone ?? runtimeConfig.public.defaultTimezone
() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone
);
type EventSlotChange = { op: "set" | "del", data: EventSlot } ;

View file

@ -394,11 +394,11 @@ function removeSlot(eventChanges: ChangeRecord<Shift>[], shift: Shift, shiftSlot
return eventChanges;
}
const { data: session } = await useAccountSession();
const sessionStore = useSessionStore();
const schedule = await useSchedule();
const runtimeConfig = useRuntimeConfig();
const timezone = computed(
() => session.value?.account?.timezone ?? runtimeConfig.public.defaultTimezone
() => sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone
);
type ShiftSlotChange = { op: "set" | "del", data: ShiftSlot } ;

View file

@ -504,10 +504,10 @@ const stretches = computed(() => [
])
const runtimeConfig = useRuntimeConfig();
const { data: session } = await useAccountSession();
const sessionStore = useSessionStore();
const debugTimezone = ref<undefined | string>();
const timezone = computed({
get: () => debugTimezone.value ?? session.value?.account?.timezone ?? runtimeConfig.public.defaultTimezone,
get: () => debugTimezone.value ?? sessionStore.account?.timezone ?? runtimeConfig.public.defaultTimezone,
set: (value: string) => { debugTimezone.value = value },
});