Files
oysqn.app/app/app.vue

120 lines
4.5 KiB
Vue

<template>
<IonApp>
<IonSplitPane content-id="main-content">
<IonMenu v-if="authStore.user" content-id="main-content" menu-id="main-menu">
<IonHeader>
<IonToolbar color="primary">
<IonTitle>OYS Borrow a Boat</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonList lines="none">
<!-- All authenticated users -->
<IonItem button router-link="/" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="homeOutline" />
<IonLabel>Home</IonLabel>
</IonItem>
<IonItem button router-link="/schedule" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="calendarOutline" />
<IonLabel>Schedule</IonLabel>
</IonItem>
<IonItem button router-link="/boat" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="boatOutline" />
<IonLabel>Boats</IonLabel>
</IonItem>
<IonItem button router-link="/reference" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="bookOutline" />
<IonLabel>Reference</IonLabel>
</IonItem>
<IonItem button router-link="/profile" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="personOutline" />
<IonLabel>Profile</IonLabel>
</IonItem>
<!-- Boatswain + Admin: schedule management -->
<template v-if="authStore.isBoatswain">
<IonItemDivider>
<IonLabel>Management</IonLabel>
</IonItemDivider>
<IonItem button router-link="/admin/intervals" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="calendarNumberOutline" />
<IonLabel>Manage Slots</IonLabel>
</IonItem>
<IonItem button router-link="/admin/templates" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="layersOutline" />
<IonLabel>Templates</IonLabel>
</IonItem>
<IonItem button router-link="/admin/reservations" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="bookmarkOutline" />
<IonLabel>Manage Bookings</IonLabel>
</IonItem>
</template>
<!-- Admin only -->
<template v-if="authStore.isAdmin">
<IonItem button router-link="/admin/user" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="peopleOutline" />
<IonLabel>Users</IonLabel>
</IonItem>
<IonItem button router-link="/admin/boat" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="constructOutline" />
<IonLabel>Manage Boats</IonLabel>
</IonItem>
<IonItem button router-link="/admin/config" router-direction="root" @click="closeMenu">
<IonIcon slot="start" :icon="settingsOutline" />
<IonLabel>Booking Rules</IonLabel>
</IonItem>
</template>
<!-- Sign out -->
<IonItemDivider />
<IonItem button @click="signOut">
<IonIcon slot="start" :icon="logOutOutline" />
<IonLabel>Sign Out</IonLabel>
<IonNote slot="end">{{ authStore.displayName }}</IonNote>
</IonItem>
</IonList>
</IonContent>
</IonMenu>
<IonRouterOutlet id="main-content" />
</IonSplitPane>
</IonApp>
</template>
<script setup lang="ts">
import {
IonApp, IonSplitPane, IonMenu, IonHeader, IonToolbar, IonTitle,
IonContent, IonList, IonItem, IonItemDivider, IonIcon, IonLabel, IonNote,
IonRouterOutlet, menuController,
} from '@ionic/vue'
import {
homeOutline, calendarOutline, boatOutline, personOutline,
bookOutline, calendarNumberOutline, peopleOutline, constructOutline, logOutOutline,
layersOutline, settingsOutline, bookmarkOutline,
} from 'ionicons/icons'
import { useAuthStore } from '~/stores/auth'
const authStore = useAuthStore()
async function closeMenu() {
await menuController.close('main-menu')
}
async function signOut() {
await closeMenu()
await authStore.signOut()
}
// Fetch member profile on app load (populates role for menu visibility)
onMounted(() => {
if (authStore.user) authStore.fetchMember()
})
// Re-fetch when user changes (e.g., after login)
watch(() => authStore.user, (u) => {
if (u) authStore.fetchMember()
else authStore.member = null
})
</script>