84 lines
3.1 KiB
Vue
84 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { RouterView } from 'vue-router';
|
|
import Button from './components/ui/button/Button.vue';
|
|
import { useUserStore } from './stores/user';
|
|
import Alert from './components/ui/alert/Alert.vue';
|
|
import AlertDescription from './components/ui/alert/AlertDescription.vue';
|
|
import Navbar from './components/Navigation/Navbar.vue';
|
|
import { cancelLOA } from './api/loa';
|
|
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
|
|
|
const userStore = useUserStore();
|
|
const headerRef = ref<HTMLDivElement | null>(null);
|
|
let resizeObserver: ResizeObserver | null = null;
|
|
|
|
function formatDate(dateStr) {
|
|
if (!dateStr) return "";
|
|
return new Date(dateStr).toLocaleDateString("en-US", {
|
|
year: "numeric",
|
|
month: "short",
|
|
day: "numeric",
|
|
});
|
|
}
|
|
|
|
//@ts-ignore
|
|
const environment = import.meta.env.VITE_ENVIRONMENT;
|
|
//@ts-ignore
|
|
const version = import.meta.env.VITE_APPLICATION_VERSION;
|
|
|
|
function updateHeaderHeight() {
|
|
if (!headerRef.value) return;
|
|
const height = headerRef.value.offsetHeight;
|
|
document.documentElement.style.setProperty('--app-header-height', `${height}px`);
|
|
}
|
|
|
|
onMounted(() => {
|
|
updateHeaderHeight();
|
|
|
|
// Gracefully skip observer setup for environments that do not support ResizeObserver.
|
|
if (typeof ResizeObserver === 'undefined' || !headerRef.value) return;
|
|
|
|
resizeObserver = new ResizeObserver(updateHeaderHeight);
|
|
resizeObserver.observe(headerRef.value);
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
resizeObserver?.disconnect();
|
|
});
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col min-h-screen" style="background-image: linear-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.25)), url('/bg.jpg');
|
|
background-size: contain;
|
|
background-attachment: fixed;
|
|
background-position: center;">
|
|
<div class="sticky top-0 bg-background z-50" ref="headerRef">
|
|
<Navbar class="flex"></Navbar>
|
|
<Alert v-if="environment == 'dev'" class="m-2 mx-auto max-w-5xl" variant="info">
|
|
<AlertDescription class="flex flex-row items-center text-wrap gap-5 mx-auto">
|
|
<p>Development environment (v{{ version }}). Features may be incomplete or unavailable.</p>
|
|
</AlertDescription>
|
|
</Alert>
|
|
<Alert v-if="userStore.user?.LOAs?.[0]" class="m-2 mx-auto max-w-5xl" variant="info">
|
|
<AlertDescription class="flex flex-row items-center text-nowrap gap-5 mx-auto">
|
|
<p
|
|
v-if="new Date(userStore.user?.LOAs?.[0].extended_till || userStore.user?.LOAs?.[0].end_date) > new Date()">
|
|
LOA until <strong>{{ formatDate(userStore.user?.LOAs?.[0].extended_till ||
|
|
userStore.user?.LOAs?.[0].end_date) }}</strong>
|
|
</p>
|
|
<p v-else>
|
|
LOA expired on <strong>{{ formatDate(userStore.user?.LOAs?.[0].extended_till ||
|
|
userStore.user?.LOAs?.[0].end_date) }}</strong>
|
|
</p>
|
|
<Button variant="secondary"
|
|
@click="async () => { await cancelLOA(userStore.user.LOAs?.[0].id); userStore.loadUser(); }">End
|
|
LOA</Button>
|
|
</AlertDescription>
|
|
</Alert>
|
|
</div>
|
|
|
|
<RouterView class="flex-1 min-h-0"></RouterView>
|
|
</div>
|
|
</template>
|