Move manager routes under /admin

This commit is contained in:
Ruslan Bakiev
2026-04-06 16:12:54 +07:00
parent 0380c54d60
commit b640885ef0
14 changed files with 83 additions and 73 deletions

View File

@@ -120,7 +120,7 @@ async function submitWithdrawal() {
</div>
<div class="flex flex-wrap gap-3">
<NuxtLink to="/messages" class="bonus-program-ghost-button">
<NuxtLink to="/admin/settings/messages" class="bonus-program-ghost-button">
Message board
</NuxtLink>
<NuxtLink to="/notifications" class="bonus-program-ghost-button">

View File

@@ -7,6 +7,8 @@ import {
definePageMeta({
middleware: ['manager-only'],
path: '/admin/bonuses/balances/:userId',
alias: ['/bonus-system/:userId'],
});
type TransactionItem = ManagerBonusAccountQuery['managerBonusAccount']['transactions'][number];
@@ -37,7 +39,7 @@ function formatDateTime(value: string) {
<template>
<section class="space-y-6">
<NuxtLink to="/bonus-system" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<NuxtLink to="/admin/bonuses/balances" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<div v-if="bonusAccountQuery.loading.value" class="manager-empty-state">
Загружаем бонусный счёт...
@@ -79,7 +81,7 @@ function formatDateTime(value: string) {
</div>
<NuxtLink
:to="`/bonus-system/withdrawals/${withdrawal.id}`"
:to="`/admin/bonuses/requests/${withdrawal.id}`"
class="text-sm font-semibold text-[#0d854a]"
>
Проверить выплату
@@ -111,7 +113,7 @@ function formatDateTime(value: string) {
<NuxtLink
v-if="transaction.orderId"
:to="`/client-orders/${transaction.orderId}`"
:to="`/admin/orders/${transaction.orderId}`"
class="text-sm font-semibold text-[#0d854a]"
>
Открыть заказ

View File

@@ -14,6 +14,8 @@ import { messengerConnectionAvatarSrc } from '~/composables/useMessengerConnecti
definePageMeta({
middleware: ['manager-only'],
path: '/admin/bonuses/:section(balances|requests|rewards)?',
alias: ['/bonus-system'],
});
type BalanceItem = ManagerBonusBalancesQuery['managerBonusBalances'][number];
@@ -38,10 +40,10 @@ const withdrawalsQuery = useQuery(ManagerWithdrawalRequestsDocument, {
});
const activeTab = computed<'balances' | 'withdrawals' | 'rewards'>(() => {
if (route.query.tab === 'withdrawals') {
if (route.path === '/admin/bonuses/requests') {
return 'withdrawals';
}
if (route.query.tab === 'rewards' || route.query.tab === 'products' || route.query.tab === 'manager') {
if (route.path === '/admin/bonuses/rewards') {
return 'rewards';
}
return 'balances';
@@ -316,7 +318,7 @@ function productVisualLabel(product: ProductCard) {
<UsersGridCard
v-for="item in visibleBalances"
:key="item.userId"
:to="`/bonus-system/${item.userId}`"
:to="`/admin/bonuses/balances/${item.userId}`"
:full-name="item.fullName"
:avatar-src="messengerConnectionAvatarSrc(usersById.get(item.userId)?.telegramConnection)"
:initials="userInitials(item.fullName)"
@@ -379,7 +381,7 @@ function productVisualLabel(product: ProductCard) {
<NuxtLink
v-for="withdrawal in visibleWithdrawals"
:key="withdrawal.id"
:to="`/bonus-system/withdrawals/${withdrawal.id}`"
:to="`/admin/bonuses/requests/${withdrawal.id}`"
class="surface-card surface-card-interactive block rounded-[30px] bg-white px-4 py-4 md:px-5"
>
<div class="grid gap-4 md:grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)_180px_140px] md:items-center md:gap-6">

View File

@@ -10,6 +10,8 @@ import {
definePageMeta({
middleware: ['manager-only'],
path: '/admin/bonuses/referrals/new',
alias: ['/bonus-system/referrals/new'],
});
type ManagerUserItem = ManagerUsersQuery['managerUsers'][number];
@@ -91,15 +93,17 @@ async function createReferral() {
createdReferralId.value = response?.data?.createReferral.id ?? '';
refereeUserId.value = '';
await linksQuery.refetch();
} catch (error: any) {
errorMessage.value = error?.message || 'Не удалось создать бонусную связку.';
} catch (error: unknown) {
errorMessage.value = error instanceof Error
? error.message
: 'Не удалось создать бонусную связку.';
}
}
</script>
<template>
<section class="space-y-6 max-w-3xl">
<NuxtLink to="/bonus-system" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<NuxtLink to="/admin/bonuses/balances" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<div class="manager-hero">
<p class="manager-eyebrow">Бонусы</p>

View File

@@ -4,6 +4,8 @@ import { AddBonusTransactionDocument } from '~/composables/graphql/generated';
definePageMeta({
middleware: ['manager-only'],
path: '/admin/bonuses/transactions/new',
alias: ['/bonus-system/transactions/new'],
});
const userId = ref('');
@@ -29,7 +31,7 @@ async function addBonus() {
<template>
<section class="space-y-6 max-w-3xl">
<NuxtLink to="/bonus-system" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<NuxtLink to="/admin/bonuses/balances" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<div class="manager-hero">
<p class="manager-eyebrow">Бонусы</p>

View File

@@ -8,6 +8,8 @@ import {
definePageMeta({
middleware: ['manager-only'],
path: '/admin/bonuses/requests/:id',
alias: ['/bonus-system/withdrawals/:id'],
});
const route = useRoute();
@@ -47,7 +49,7 @@ async function reviewWithdrawal() {
<template>
<section class="space-y-6 max-w-3xl">
<NuxtLink to="/bonus-system" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<NuxtLink to="/admin/bonuses/requests" class="text-sm font-semibold text-[#0d854a]"> Назад к бонусам</NuxtLink>
<div v-if="withdrawalsQuery.loading.value" class="manager-empty-state">
Загружаем заявку на вывод...

View File

@@ -14,6 +14,8 @@ import { formatOrderCode } from '~/composables/useOrderCodePresentation';
definePageMeta({
middleware: ['manager-only'],
path: '/admin/orders/:id',
alias: ['/client-orders/:id'],
});
const route = useRoute();
@@ -316,7 +318,7 @@ watch(
<template v-else>
<div class="surface-card rounded-3xl px-5 py-4">
<div class="flex flex-wrap items-center gap-3">
<NuxtLink to="/client-orders" class="text-sm font-semibold text-[#0d854a]">
<NuxtLink to="/admin/orders" class="text-sm font-semibold text-[#0d854a]">
Назад к заказам клиентов
</NuxtLink>
<span class="hidden h-4 w-px bg-[#d8e4dd] md:block" />

View File

@@ -15,6 +15,8 @@ import { formatPrice } from '~/composables/useOrderDetailPresentation';
definePageMeta({
middleware: ['manager-only'],
path: '/admin/orders',
alias: ['/client-orders'],
});
type ManagerOrderItem = ManagerOrdersQuery['managerOrders'][number];
@@ -264,7 +266,7 @@ const calendarOptions = computed(() => ({
};
},
eventClick: ({ event }: { event: { id: string } }) => {
void router.push(`/client-orders/${event.id}`);
void router.push(`/admin/orders/${event.id}`);
},
}));
</script>
@@ -333,7 +335,7 @@ const calendarOptions = computed(() => ({
<OrdersOrderSummaryCard
v-for="order in visibleOrders"
:key="order.id"
:to="`/client-orders/${order.id}`"
:to="`/admin/orders/${order.id}`"
:code="order.code"
:status="order.status"
:created-at="order.createdAt"

View File

@@ -13,6 +13,8 @@ import { messengerConnectionAvatarSrc } from '~/composables/useMessengerConnecti
definePageMeta({
middleware: ['manager-only'],
path: '/admin/orders/:mode(clients|requests)/:id',
alias: ['/clients/:id'],
});
type ManagerUserItem = ManagerUsersDetailQuery['managerUsers'][number];
@@ -21,8 +23,9 @@ type RequestItem = RegistrationRequestsQuery['registrationRequests'][number];
const route = useRoute();
const entityId = computed(() => String(route.params.id || ''));
const isRequestMode = computed(() => route.query.tab === 'requests');
const backTarget = computed(() => '/clients');
const entityMode = computed(() => String(route.params.mode || 'clients'));
const isRequestMode = computed(() => entityMode.value === 'requests');
const backTarget = computed(() => '/admin/orders/clients');
const usersQuery = useQuery(ManagerUsersDetailDocument);
const requestsQuery = useQuery(RegistrationRequestsDocument, {
@@ -221,7 +224,7 @@ async function rejectRequest() {
<OrdersOrderSummaryCard
v-for="order in visibleUserOrders"
:key="order.id"
:to="`/client-orders/${order.id}`"
:to="`/admin/orders/${order.id}`"
:code="order.code"
:status="order.status"
:created-at="order.createdAt"

View File

@@ -5,6 +5,8 @@ import { messengerConnectionAvatarSrc } from '~/composables/useMessengerConnecti
definePageMeta({
middleware: ['manager-only'],
path: '/admin/orders/clients',
alias: ['/clients'],
});
const search = ref('');
@@ -64,7 +66,7 @@ function userInitials(fullName: string) {
search-placeholder="Имя, компания или email"
>
<template #controls>
<NuxtLink to="/clients/invite" class="btn btn-primary border-0">
<NuxtLink to="/admin/orders/clients/invite" class="btn btn-primary border-0">
Пригласить
</NuxtLink>
</template>
@@ -81,7 +83,7 @@ function userInitials(fullName: string) {
<UsersGridCard
v-for="user in visibleUsers"
:key="user.id"
:to="`/clients/${user.id}`"
:to="`/admin/orders/clients/${user.id}`"
:full-name="user.fullName"
:avatar-src="messengerConnectionAvatarSrc(user.telegramConnection)"
:initials="userInitials(user.fullName)"

View File

@@ -4,6 +4,8 @@ import { CreateInvitationDocument } from '~/composables/graphql/generated';
definePageMeta({
middleware: ['manager-only'],
path: '/admin/orders/clients/invite',
alias: ['/clients/invite'],
});
const email = ref('');
@@ -37,7 +39,7 @@ async function createInvitation() {
<template>
<section class="space-y-6 max-w-3xl">
<NuxtLink to="/clients" class="text-sm font-semibold text-[#0d854a]"> Назад к пользователям</NuxtLink>
<NuxtLink to="/admin/orders/clients" class="text-sm font-semibold text-[#0d854a]"> Назад к пользователям</NuxtLink>
<div class="manager-hero">
<p class="manager-eyebrow">Приглашение</p>

View File

@@ -7,6 +7,8 @@ import {
definePageMeta({
middleware: ['manager-only'],
path: '/admin/settings/messages',
alias: ['/messages'],
});
type TemplateItem = NotificationTemplatesQuery['notificationTemplates'][number];