Simplify order detail layout

This commit is contained in:
Ruslan Bakiev
2026-04-04 11:05:31 +07:00
parent 691990f992
commit 7dc0f59ffb
3 changed files with 49 additions and 77 deletions

View File

@@ -0,0 +1,9 @@
export function orderLineStateText(totalPrice?: number | null) {
return totalPrice == null
? 'Цена уточняется менеджером'
: 'Цена согласована менеджером';
}
export function orderDeliveryStateText(deliveryTerms?: string | null) {
return deliveryTerms?.trim() || 'Доставка уточняется менеджером';
}

View File

@@ -5,9 +5,12 @@ import {
CompleteOrderDocument,
ManagerFinalizeOrderDocument,
ManagerOrdersDocument,
ManagerSetOrderOfferDocument,
StartOrderWorkDocument,
} from '~/composables/graphql/generated';
import {
orderDeliveryStateText,
orderLineStateText,
} from '~/composables/useOrderDetailPresentation';
definePageMeta({
middleware: ['manager-only'],
@@ -18,7 +21,6 @@ const orderId = computed(() => String(route.params.id || ''));
const ordersQuery = useQuery(ManagerOrdersDocument, { status: null });
const setOfferMutation = useMutation(ManagerSetOrderOfferDocument);
const finalizeMutation = useMutation(ManagerFinalizeOrderDocument);
const blockMutation = useMutation(BlockOrderDocument);
const startWorkMutation = useMutation(StartOrderWorkDocument);
@@ -28,43 +30,10 @@ const currentOrder = computed(() =>
(ordersQuery.result.value?.managerOrders ?? []).find((item) => item.id === orderId.value),
);
const offerForm = reactive({
deliveryTerms: '',
deliveryFee: 0,
totalPrice: 0,
});
watchEffect(() => {
if (!currentOrder.value) {
return;
}
offerForm.deliveryTerms = currentOrder.value.deliveryTerms || 'Доставка 3-5 дней';
offerForm.deliveryFee = Number(currentOrder.value.deliveryFee ?? 1000);
offerForm.totalPrice = Number(currentOrder.value.totalPrice ?? 12500);
});
async function refetchOrder() {
await ordersQuery.refetch({ status: null });
}
async function publishOffer() {
if (!currentOrder.value) {
return;
}
await setOfferMutation.mutate({
input: {
orderId: currentOrder.value.id,
deliveryTerms: offerForm.deliveryTerms,
deliveryFee: Number(offerForm.deliveryFee),
totalPrice: Number(offerForm.totalPrice),
},
});
await refetchOrder();
}
async function approveOrder() {
if (!currentOrder.value) {
return;
@@ -134,49 +103,38 @@ async function completeOrder() {
<h1 class="manager-title">{{ currentOrder.code }}</h1>
</div>
<div class="grid gap-4 lg:grid-cols-[1.1fr_0.9fr]">
<div class="space-y-4">
<OrdersOrderStatusTimelineCard
:status="currentOrder.status"
:created-at="currentOrder.createdAt"
/>
<div class="space-y-4">
<OrdersOrderStatusTimelineCard
:status="currentOrder.status"
:created-at="currentOrder.createdAt"
/>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Состав заказа</h2>
<ul class="mt-4 space-y-3">
<li v-for="item in currentOrder.items" :key="item.id" class="manager-mini-card text-sm text-[#123824]">
{{ item.productName }} × {{ item.quantity }}
</li>
</ul>
</div>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Состав заказа</h2>
<ul class="mt-4 space-y-3">
<li v-for="item in currentOrder.items" :key="item.id" class="manager-mini-card space-y-2">
<p class="text-sm font-semibold text-[#123824]">{{ item.productName }} × {{ item.quantity }}</p>
<p class="text-sm text-[#5c7b69]">{{ orderLineStateText(currentOrder.totalPrice) }}</p>
</li>
</ul>
</div>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Доставка</h2>
<div class="mt-4 grid gap-3 md:grid-cols-2">
<div class="manager-mini-card text-sm text-[#123824]">
Адрес: {{ currentOrder.deliveryAddress || 'не выбран' }}
</div>
<div class="manager-mini-card text-sm text-[#123824]">
Условия: {{ currentOrder.deliveryTerms || 'еще не указаны' }}
</div>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Доставка</h2>
<div class="mt-4 space-y-3">
<div class="manager-mini-card text-sm text-[#123824]">
Адрес: {{ currentOrder.deliveryAddress || 'Адрес пока не указан' }}
</div>
<div class="manager-mini-card text-sm text-[#123824]">
{{ orderDeliveryStateText(currentOrder.deliveryTerms) }}
</div>
</div>
</div>
<div class="space-y-4">
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Оффер</h2>
<div class="mt-4 space-y-3">
<input v-model="offerForm.deliveryTerms" class="input manager-field w-full" placeholder="Условия доставки">
<input v-model="offerForm.deliveryFee" type="number" class="input manager-field w-full" placeholder="Стоимость доставки">
<input v-model="offerForm.totalPrice" type="number" class="input manager-field w-full" placeholder="Итоговая стоимость">
<button class="btn btn-primary border-0" @click="publishOffer">Публиковать оффер</button>
</div>
</div>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Действия</h2>
<div class="mt-4 flex flex-wrap gap-2">
<div class="surface-card rounded-3xl p-5">
<div class="flex flex-wrap items-center justify-between gap-3">
<h2 class="text-xl font-bold text-[#123824]">Действия менеджера</h2>
<div class="flex flex-wrap gap-2">
<button class="btn btn-success btn-sm border-0" @click="approveOrder">Подтвердить</button>
<button class="btn btn-error btn-sm border-0" @click="rejectOrder">Отклонить</button>
<button class="btn btn-warning btn-sm border-0" @click="blockOrder">Заблокировать</button>

View File

@@ -4,6 +4,10 @@ import {
MyOrdersDocument,
type MyOrdersQuery,
} from '~/composables/graphql/generated';
import {
orderDeliveryStateText,
orderLineStateText,
} from '~/composables/useOrderDetailPresentation';
type OrderItem = MyOrdersQuery['myOrders'][number];
@@ -46,21 +50,22 @@ const currentOrder = computed<OrderItem | null>(() =>
<li
v-for="item in currentOrder.items"
:key="item.id"
class="manager-mini-card text-sm text-[#123824]"
class="manager-mini-card space-y-2"
>
{{ item.productName }} × {{ item.quantity }}
<p class="text-sm font-semibold text-[#123824]">{{ item.productName }} × {{ item.quantity }}</p>
<p class="text-sm text-[#5c7b69]">{{ orderLineStateText(currentOrder.totalPrice) }}</p>
</li>
</ul>
</div>
<div class="surface-card rounded-3xl p-5">
<h2 class="text-xl font-bold text-[#123824]">Доставка</h2>
<div class="mt-4 grid gap-3 md:grid-cols-2">
<div class="mt-4 space-y-3">
<div class="manager-mini-card text-sm text-[#123824]">
Адрес: {{ currentOrder.deliveryAddress || 'не выбран' }}
Адрес: {{ currentOrder.deliveryAddress || 'Адрес пока не указан' }}
</div>
<div class="manager-mini-card text-sm text-[#123824]">
Условия: {{ currentOrder.deliveryTerms || 'еще не указаны' }}
{{ orderDeliveryStateText(currentOrder.deliveryTerms) }}
</div>
</div>
</div>