Show customer card in manager order header

This commit is contained in:
Ruslan Bakiev
2026-04-07 10:17:04 +07:00
parent c70328d352
commit 5eafdd4e8f

View File

@@ -1,12 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable'; import { useMutation, useQuery } from '@vue/apollo-composable';
import { import {
ManagerUsersDetailDocument,
ManagerSetOrderOfferDocument, ManagerSetOrderOfferDocument,
ManagerSetOrderStatusDocument, ManagerSetOrderStatusDocument,
OrderStatus, OrderStatus,
OrderDetailDocument, OrderDetailDocument,
type OrderDetailQuery, type OrderDetailQuery,
type ManagerUsersDetailQuery,
} from '~/composables/graphql/generated'; } from '~/composables/graphql/generated';
import { messengerConnectionAvatarSrc } from '~/composables/useMessengerConnectionPresentation';
import { import {
formatPrice, formatPrice,
} from '~/composables/useOrderDetailPresentation'; } from '~/composables/useOrderDetailPresentation';
@@ -22,6 +25,7 @@ const route = useRoute();
const orderId = computed(() => String(route.params.id || '')); const orderId = computed(() => String(route.params.id || ''));
type ManagerOrderItem = NonNullable<OrderDetailQuery['order']>; type ManagerOrderItem = NonNullable<OrderDetailQuery['order']>;
type ManagerCustomerItem = ManagerUsersDetailQuery['managerUsers'][number];
type StatusOption = { type StatusOption = {
value: OrderStatus; value: OrderStatus;
label: string; label: string;
@@ -30,6 +34,7 @@ type StatusOption = {
const orderQuery = useQuery(OrderDetailDocument, () => ({ const orderQuery = useQuery(OrderDetailDocument, () => ({
id: orderId.value, id: orderId.value,
})); }));
const managerUsersQuery = useQuery(ManagerUsersDetailDocument);
const setOfferMutation = useMutation(ManagerSetOrderOfferDocument); const setOfferMutation = useMutation(ManagerSetOrderOfferDocument);
const setOrderStatusMutation = useMutation(ManagerSetOrderStatusDocument); const setOrderStatusMutation = useMutation(ManagerSetOrderStatusDocument);
@@ -51,6 +56,28 @@ const currentOrder = computed<ManagerOrderItem | null>(() =>
); );
const currentOrderCode = computed(() => formatOrderCode(currentOrder.value?.code)); const currentOrderCode = computed(() => formatOrderCode(currentOrder.value?.code));
const currentCustomer = computed<ManagerCustomerItem | null>(() => {
const customerId = currentOrder.value?.customerId;
if (!customerId) {
return null;
}
return (managerUsersQuery.result.value?.managerUsers ?? []).find((item) => item.id === customerId) ?? null;
});
function userInitials(fullName: string) {
const parts = fullName
.trim()
.split(/\s+/)
.filter(Boolean)
.slice(0, 2);
if (!parts.length) {
return 'FR';
}
return parts.map((part) => part[0]?.toUpperCase() ?? '').join('');
}
watch( watch(
currentOrder, currentOrder,
@@ -324,9 +351,29 @@ watch(
<template #actions> <template #actions>
<NuxtLink <NuxtLink
:to="`/admin/orders/clients/${currentOrder.customerId}`" :to="`/admin/orders/clients/${currentOrder.customerId}`"
class="btn rounded-full border border-[#d7e6dc] bg-white px-5 text-[#123824] hover:border-[#bed6c7] hover:bg-[#f6fbf8]" class="surface-card surface-card-interactive flex min-w-[220px] items-center gap-3 rounded-[24px] px-4 py-3"
> >
Открыть клиента <img
v-if="currentCustomer && messengerConnectionAvatarSrc(currentCustomer.telegramConnection)"
:src="messengerConnectionAvatarSrc(currentCustomer.telegramConnection)"
:alt="currentCustomer.fullName"
class="h-12 w-12 rounded-[16px] object-cover"
>
<div
v-else
class="flex h-12 w-12 shrink-0 items-center justify-center rounded-[16px] bg-[linear-gradient(135deg,#dff7e9_0%,#c2ead3_100%)] text-sm font-black text-[#123824]"
>
{{ userInitials(currentCustomer?.fullName || 'Fregat') }}
</div>
<div class="min-w-0 text-left">
<p class="truncate text-sm font-bold text-[#123824]">
{{ currentCustomer?.fullName || 'Клиент' }}
</p>
<p class="truncate text-xs text-[#5c7b69]">
{{ currentCustomer?.companyName || currentCustomer?.email || 'Открыть карточку клиента' }}
</p>
</div>
</NuxtLink> </NuxtLink>
</template> </template>
</UiBackHeader> </UiBackHeader>