Files
web-frontend/app/app.vue
2026-04-06 16:12:54 +07:00

134 lines
3.8 KiB
Vue

<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: 'messages',
label: 'Сообщения',
active: true,
to: {
path: '/admin/settings/messages',
},
},
];
}
return [];
});
</script>
<template>
<div :class="isBonusProgramPage ? 'bonus-program-shell' : 'lk-shell'" data-theme="aqua">
<UiAppHeader v-if="!isLoginPage && !isBonusProgramPage" />
<main
:class="isBonusProgramPage
? 'bonus-program-main'
: ['mx-auto w-full max-w-[1440px] p-4 pt-[104px] md:p-6 md:pt-[112px] lg:p-8 lg:pt-[118px]', hasManagerDock ? 'pb-[116px] md:pb-[128px]' : '']"
>
<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="isBonusProgramPage
? 'bonus-program-stage'
: ['lk-content-canvas', { 'lk-content-canvas--with-tabs': managerPageTabs.length }]"
>
<NuxtPage />
</div>
</main>
<UiAppManagerDock v-if="hasManagerDock" />
</div>
</template>