init
This commit is contained in:
96
src/components/layout/AppShell.vue
Normal file
96
src/components/layout/AppShell.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import TauriTitlebar from './TauriTitlebar.vue';
|
||||
import SideNav from './SideNav.vue';
|
||||
import BottomNav from './BottomNav.vue';
|
||||
import { useAuthStore } from '@/stores/auth.store';
|
||||
|
||||
const route = useRoute();
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const isTauri = typeof window !== 'undefined' && !!window.__TAURI__;
|
||||
|
||||
// Hide nav on auth/onboarding routes
|
||||
const showNav = computed(() =>
|
||||
authStore.isAuthenticated &&
|
||||
!['login', 'register', 'setup'].includes(route.name as string),
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="shell" :class="{ 'shell--tauri': isTauri }">
|
||||
<!-- Grain texture overlay (fixed, pointer-events none) -->
|
||||
<div class="shell__grain" aria-hidden="true" />
|
||||
|
||||
<!-- Tauri custom titlebar -->
|
||||
<TauriTitlebar />
|
||||
|
||||
<div class="shell__body">
|
||||
<!-- Desktop sidebar navigation -->
|
||||
<SideNav v-if="showNav" class="shell__sidenav" />
|
||||
|
||||
<!-- Main content area -->
|
||||
<main class="shell__main" :class="{ 'shell__main--no-nav': !showNav }">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Mobile bottom navigation -->
|
||||
<BottomNav v-if="showNav" class="shell__bottom-nav" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shell {
|
||||
height: 100dvh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--color-base);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&__grain {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: var(--z-tooltip);
|
||||
pointer-events: none;
|
||||
background-image: url('@/assets/grain.svg');
|
||||
background-repeat: repeat;
|
||||
opacity: 0.35;
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__sidenav {
|
||||
// Desktop only
|
||||
@include mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__main {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
&--no-nav {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__bottom-nav {
|
||||
// Mobile only
|
||||
@include tablet {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user