Files
crewli/apps/app/src/App.vue

57 lines
1.7 KiB
Vue

<script setup lang="ts">
import { useTheme } from 'vuetify'
import ScrollToTop from '@core/components/ScrollToTop.vue'
import initCore from '@core/initCore'
import { initConfigStore, useConfigStore } from '@core/stores/config'
import { hexToRgb } from '@core/utils/colorConverter'
import { useAuthStore } from '@/stores/useAuthStore'
import { useNotificationStore } from '@/stores/useNotificationStore'
const { global } = useTheme()
initCore()
initConfigStore()
const configStore = useConfigStore()
const authStore = useAuthStore()
const notificationStore = useNotificationStore()
// Validate stored token on app startup — must complete before rendering protected content
authStore.initialize()
</script>
<template>
<VLocaleProvider :rtl="configStore.isAppRTL">
<VApp :style="`--v-global-theme-primary: ${hexToRgb(global.current.value.colors.primary)}`">
<!-- Show loading state while validating auth token -->
<template v-if="!authStore.isInitialized">
<div class="d-flex align-center justify-center" style="min-height: 100vh;">
<VProgressCircular indeterminate color="primary" size="48" />
</div>
</template>
<!-- Only render app shell after auth is resolved -->
<template v-else>
<RouterView />
<ScrollToTop />
</template>
</VApp>
<!-- Global notification snackbar -->
<VSnackbar
v-model="notificationStore.visible"
:color="notificationStore.type"
:timeout="notificationStore.timeout"
location="top end"
>
{{ notificationStore.message }}
<template #actions>
<VBtn variant="text" @click="notificationStore.hide()">
Close
</VBtn>
</template>
</VSnackbar>
</VLocaleProvider>
</template>