Files
web-frontend/app/app.vue
2026-04-09 16:03:32 +07:00

169 lines
4.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable';
import { MeDocument } from '~/composables/graphql/generated';
import { hasManagerAccess } from '~/utils/roles';
const route = useRoute();
const isLoginPage = computed(() => route.path === '/login');
const isBonusProgramPage = computed(() => route.path === '/bonus-program');
const meQuery = useQuery(MeDocument);
const hasManagerDock = computed(() => (
!isLoginPage.value && !isBonusProgramPage.value && hasManagerAccess(meQuery.result.value?.me?.role)
));
const managerPageTabs = computed(() => {
if (!hasManagerDock.value) {
return [];
}
if (
route.path === '/admin/orders'
|| route.path.startsWith('/admin/orders/')
) {
return [
{
key: 'orders',
label: 'Заказы',
active: route.path === '/admin/orders'
|| (
/^\/admin\/orders\/[^/]+$/.test(route.path)
&& !route.path.startsWith('/admin/orders/clients')
&& !route.path.startsWith('/admin/orders/requests')
),
to: {
path: '/admin/orders',
},
},
{
key: 'clients',
label: 'Клиенты',
active: route.path === '/admin/orders/clients'
|| route.path.startsWith('/admin/orders/clients/')
|| route.path.startsWith('/admin/orders/requests/'),
to: {
path: '/admin/orders/clients',
},
},
];
}
if (route.path.startsWith('/admin/bonuses')) {
return [
{
key: 'balances',
label: 'Бонусные счета',
active: route.path === '/admin/bonuses'
|| route.path === '/admin/bonuses/balances'
|| route.path.startsWith('/admin/bonuses/balances/')
|| route.path.startsWith('/admin/bonuses/referrals/')
|| route.path.startsWith('/admin/bonuses/transactions/'),
to: {
path: '/admin/bonuses/balances',
},
},
{
key: 'withdrawals',
label: 'Заявки на выплату',
active: route.path === '/admin/bonuses/requests'
|| route.path.startsWith('/admin/bonuses/requests/'),
to: {
path: '/admin/bonuses/requests',
},
},
{
key: 'rewards',
label: 'Вознаграждения',
active: route.path === '/admin/bonuses/rewards',
to: {
path: '/admin/bonuses/rewards',
},
},
];
}
if (route.path.startsWith('/admin/settings')) {
return [
{
key: 'catalog',
label: 'Каталог',
active: route.path === '/admin/settings/catalog',
to: {
path: '/admin/settings/catalog',
},
},
{
key: 'messages',
label: 'Сообщения',
active: route.path === '/admin/settings/messages',
to: {
path: '/admin/settings/messages',
},
},
{
key: 'sync',
label: '1С',
active: route.path === '/admin/settings/sync',
to: {
path: '/admin/settings/sync',
},
},
];
}
return [];
});
const mainClass = computed(() => {
if (isBonusProgramPage.value) {
return 'bonus-program-main';
}
if (isLoginPage.value) {
return 'mx-auto flex min-h-screen w-full max-w-[1440px] items-center justify-center p-4 md:p-6 lg:p-8';
}
return [
'mx-auto w-full max-w-[1440px] p-4 pt-[104px] md:p-6 md:pt-[112px] lg:p-8 lg:pt-[118px]',
hasManagerDock.value ? 'pb-[116px] md:pb-[128px]' : '',
];
});
const pageFrameClass = computed(() => {
if (isBonusProgramPage.value) {
return 'bonus-program-stage';
}
if (isLoginPage.value) {
return '';
}
return ['lk-content-canvas', { 'lk-content-canvas--with-tabs': managerPageTabs.value.length }];
});
</script>
<template>
<div :class="isBonusProgramPage ? 'bonus-program-shell' : 'lk-shell'" data-theme="aqua">
<UiAppHeader v-if="!isLoginPage && !isBonusProgramPage" />
<main :class="mainClass">
<div v-if="managerPageTabs.length && !isBonusProgramPage" class="lk-page-tabs-shell">
<nav class="manager-page-tabs" aria-label="Разделы страницы">
<NuxtLink
v-for="tab in managerPageTabs"
:key="tab.key"
:to="tab.to"
class="manager-page-tab"
:class="{ 'manager-page-tab--active': tab.active }"
>
{{ tab.label }}
</NuxtLink>
</nav>
</div>
<div :class="pageFrameClass">
<NuxtPage />
</div>
</main>
<UiAppManagerDock v-if="hasManagerDock" />
</div>
</template>