Fix profile route structure

This commit is contained in:
Ruslan Bakiev
2026-04-03 14:36:57 +07:00
parent 2862f668e3
commit 5bb0e3928f

113
app/pages/profile/index.vue Normal file
View File

@@ -0,0 +1,113 @@
<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable';
import {
MyCounterpartyProfileDocument,
MyDeliveryAddressesDocument,
MyMessengerConnectionsDocument,
type MyDeliveryAddressesQuery,
} from '~/composables/graphql/generated';
import { isCounterpartyProfileComplete } from '~/composables/useCounterpartyProfile';
type MessengerItem = {
type: 'TELEGRAM' | 'MAX';
isActive: boolean;
};
type DeliveryAddressItem = MyDeliveryAddressesQuery['myDeliveryAddresses'][number];
const profileQuery = useQuery(MyCounterpartyProfileDocument);
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
const deliveryAddressesQuery = useQuery(MyDeliveryAddressesDocument);
const profileIsComplete = computed(() => isCounterpartyProfileComplete(profileQuery.result.value?.myCounterpartyProfile));
const telegramConnected = computed(() =>
Boolean(
connectionsQuery.result.value?.myMessengerConnections?.find(
(item: MessengerItem) => item.type === 'TELEGRAM' && item.isActive,
),
),
);
const maxConnected = computed(() =>
Boolean(
connectionsQuery.result.value?.myMessengerConnections?.find(
(item: MessengerItem) => item.type === 'MAX' && item.isActive,
),
),
);
const connectedMessengerCount = computed(() => Number(telegramConnected.value) + Number(maxConnected.value));
const companyNamePreview = computed(() => profileQuery.result.value?.myCounterpartyProfile?.companyName?.trim() || '');
const notificationsSummary = computed(() => {
if (connectedMessengerCount.value === 0) {
return 'Подключите Telegram и Max, чтобы получать статусы заказов и важные уведомления.';
}
if (connectedMessengerCount.value === 1) {
return 'Подключен один канал. Добавьте второй канал для резервного уведомления.';
}
return 'Оба канала подключены. Уведомления будут приходить в Telegram и Max.';
});
const deliveryAddresses = computed<DeliveryAddressItem[]>(() => deliveryAddressesQuery.result.value?.myDeliveryAddresses ?? []);
const defaultDeliveryAddress = computed(() => deliveryAddresses.value.find((item) => item.isDefault) ?? null);
</script>
<template>
<section class="space-y-6">
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Профиль</h1>
<div class="grid gap-4 md:grid-cols-3">
<NuxtLink
to="/profile/counterparty"
class="block rounded-3xl p-5 transition hover:shadow-md"
:class="profileIsComplete ? 'bg-white' : 'bg-[#fff8e6]'"
>
<div class="mb-2 flex items-start justify-between gap-2">
<p class="text-lg font-bold text-[#123824]">Карточка контрагента</p>
<span v-if="!profileIsComplete" class="text-[#b37a00]" aria-hidden="true"></span>
</div>
<p class="text-sm text-[#355947]">
{{
profileIsComplete
? `Компания: ${companyNamePreview || 'данные сохранены'}`
: 'Пожалуйста, заполните карточку контрагента, чтобы получить максимум возможностей личного кабинета.'
}}
</p>
</NuxtLink>
<NuxtLink to="/profile/notifications" class="block rounded-3xl bg-white p-5 transition hover:shadow-md">
<div class="mb-2 flex items-center justify-between gap-2">
<p class="text-lg font-bold text-[#123824]">Уведомления</p>
</div>
<div class="mb-2 flex items-center justify-end gap-2">
<span
class="inline-flex h-8 w-8 items-center justify-center rounded-full text-xs font-bold"
:class="telegramConnected ? 'bg-[#def6ea] text-[#0d854a]' : 'bg-[#eceff3] text-[#6b7280]'"
>
TG
</span>
<span
class="inline-flex h-8 w-8 items-center justify-center rounded-full text-xs font-bold"
:class="maxConnected ? 'bg-[#def6ea] text-[#0d854a]' : 'bg-[#eceff3] text-[#6b7280]'"
>
MX
</span>
</div>
<p class="text-sm text-[#355947]">{{ notificationsSummary }}</p>
</NuxtLink>
<NuxtLink to="/profile/addresses" class="block rounded-3xl bg-white p-5 transition hover:shadow-md">
<p class="mb-2 text-lg font-bold text-[#123824]">Адреса доставки</p>
<p class="text-sm text-[#355947]">
{{
defaultDeliveryAddress
? `Основной: ${defaultDeliveryAddress.label || defaultDeliveryAddress.address}`
: 'Добавьте первый адрес доставки, чтобы быстро оформлять заказы в корзине.'
}}
</p>
</NuxtLink>
</div>
</section>
</template>