Files
portal/app/resources/js/components/AppShell.vue
T
Дмитрий ef0f7c803f feat(sales): каркас фронта портала — layout, роутер, вход, период-пикер
Task 0.7: SalesLayout (сайдбар ОТДЕЛ ПРОДАЖ, 2 секции nav, boss-only для head), SalesLoginView (реальные email+пароль, не демо-кнопки), сторы salesAuth/salesPeriod, api/sales.ts, PeriodPicker (этот/прошлый/позапрошлый/произвольный), HelpHint (?). Роуты /sales/* с гардом (токен→login, boss-only→/sales). Заглушка SalesStubView для экранов будущих фаз. Vitest SalesLogin 5/5, весь фронт 1005 без регрессий, type-check/lint чисто. Вёрстка по демо v8_sales.html. Один эскейп на сессию.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 13:27:04 +03:00

40 lines
1.9 KiB
Vue

<script setup lang="ts">
/**
* Корневой shell приложения. Мапит meta.layout текущего route'а на layout-компонент.
*
* meta.layout = 'auth' → AuthLayout (двухпанельный для login/register/2fa/forgot/recovery-use).
* meta.layout = 'error' → RouterView напрямую (ErrorView сам предоставляет v-app + теало-нуар bg).
* meta.layout = 'public' → PublicLayout (юр-страницы и цены, без auth).
* meta.layout не задан или 'app' → AppLayout (sidebar + topbar для авторизованных страниц).
*
* Источник дизайна: liderra_v8_handoff/concepts/v8_login.html (auth),
* v8_dashboard.html (app), v8_errors.html (error).
*/
import { computed, defineAsyncComponent, type Component } from 'vue';
import { RouterView, useRoute } from 'vue-router';
import AdminLayout from '../layouts/AdminLayout.vue';
import AppLayout from '../layouts/AppLayout.vue';
import AuthLayout from '../layouts/AuthLayout.vue';
import PublicLayout from '../layouts/PublicLayout.vue';
import SalesLayout from '../layouts/SalesLayout.vue';
const route = useRoute();
const layoutName = computed(() => route.meta.layout ?? 'app');
// Dev-only overlay: tree-shaken from production bundle via import.meta.env.DEV guard.
const DevIndexOverlay: Component | null = import.meta.env.DEV
? defineAsyncComponent(() => import('./DevIndexOverlay.vue'))
: null;
</script>
<template>
<AuthLayout v-if="layoutName === 'auth'" />
<RouterView v-else-if="layoutName === 'error'" />
<RouterView v-else-if="layoutName === 'sales-login'" />
<PublicLayout v-else-if="layoutName === 'public'" />
<AdminLayout v-else-if="layoutName === 'admin'" />
<SalesLayout v-else-if="layoutName === 'sales'" />
<AppLayout v-else />
<component :is="DevIndexOverlay" v-if="DevIndexOverlay" />
</template>