121 lines
5.3 KiB
Vue
121 lines
5.3 KiB
Vue
<script setup lang="ts">
|
||
import { useMutation } from '@vue/apollo-composable';
|
||
import { SubmitCalculationOrderDocument } from '~/composables/graphql/generated';
|
||
import { useCounterpartyProfile } from '~/composables/useCounterpartyProfile';
|
||
|
||
const productName = ref('');
|
||
const quantity = ref(1);
|
||
const width = ref(100);
|
||
const thickness = ref(50);
|
||
const color = ref('прозрачный');
|
||
|
||
const { mutate, loading, onDone, onError } = useMutation(SubmitCalculationOrderDocument);
|
||
const success = ref('');
|
||
const errorMessage = ref('');
|
||
const calculatedVolume = computed(() => Number(quantity.value) * Number(width.value) * Number(thickness.value));
|
||
const { isComplete: isCounterpartyComplete, loading: counterpartyLoading } = useCounterpartyProfile();
|
||
|
||
onDone((result) => {
|
||
success.value = `Заявка ${result.data?.submitCalculationOrder.code} отправлена`;
|
||
errorMessage.value = '';
|
||
});
|
||
|
||
onError((error) => {
|
||
errorMessage.value = error.message;
|
||
success.value = '';
|
||
});
|
||
|
||
function submit() {
|
||
if (!isCounterpartyComplete.value) {
|
||
errorMessage.value = 'Сначала заполните карточку контрагента в профиле.';
|
||
success.value = '';
|
||
return;
|
||
}
|
||
|
||
mutate({
|
||
input: {
|
||
productName: productName.value,
|
||
quantity: Number(quantity.value),
|
||
parameters: {
|
||
width: Number(width.value),
|
||
thickness: Number(thickness.value),
|
||
color: color.value,
|
||
},
|
||
},
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<section class="space-y-6">
|
||
<div class="text-center">
|
||
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Корзина и checkout</h1>
|
||
<p class="mt-1 text-sm text-[#28543f]/80">Заполните параметры и отправьте расчёт менеджеру.</p>
|
||
</div>
|
||
|
||
<div class="mx-auto max-w-4xl rounded-[30px] p-1 shadow-[0_26px_60px_rgba(13,133,74,0.18)]">
|
||
<div class="surface-card grid gap-6 rounded-[26px] p-5 md:grid-cols-[1.45fr_1fr] md:p-6">
|
||
<div class="space-y-3">
|
||
<div v-if="counterpartyLoading.value" class="alert">
|
||
Проверяем карточку контрагента...
|
||
</div>
|
||
<div v-else-if="!isCounterpartyComplete" class="alert alert-warning">
|
||
Для оформления заявки заполните карточку контрагента в
|
||
<NuxtLink to="/profile" class="link link-hover font-semibold">профиле</NuxtLink>.
|
||
</div>
|
||
|
||
<label class="form-control">
|
||
<span class="label-text font-semibold text-[#194631]">Название позиции</span>
|
||
<input v-model="productName" type="text" class="input input-bordered border-[#d0e8d8] bg-white/80">
|
||
</label>
|
||
<div class="grid gap-3 sm:grid-cols-2">
|
||
<label class="form-control">
|
||
<span class="label-text font-semibold text-[#194631]">Количество</span>
|
||
<input v-model="quantity" type="number" min="1" class="input input-bordered border-[#d0e8d8] bg-white/80">
|
||
</label>
|
||
<label class="form-control">
|
||
<span class="label-text font-semibold text-[#194631]">Ширина</span>
|
||
<input v-model="width" type="number" min="1" class="input input-bordered border-[#d0e8d8] bg-white/80">
|
||
</label>
|
||
<label class="form-control">
|
||
<span class="label-text font-semibold text-[#194631]">Толщина</span>
|
||
<input v-model="thickness" type="number" min="1" class="input input-bordered border-[#d0e8d8] bg-white/80">
|
||
</label>
|
||
<label class="form-control">
|
||
<span class="label-text font-semibold text-[#194631]">Цвет</span>
|
||
<input v-model="color" type="text" class="input input-bordered border-[#d0e8d8] bg-white/80">
|
||
</label>
|
||
</div>
|
||
<button class="btn border-0 bg-[#139957] text-white hover:bg-[#0d854a]" :disabled="loading || counterpartyLoading.value || !isCounterpartyComplete" @click="submit">
|
||
{{ loading ? 'Отправляем…' : 'Отправить менеджеру' }}
|
||
</button>
|
||
</div>
|
||
|
||
<aside class="rounded-2xl border border-[#cde8d8] bg-white/75 p-4">
|
||
<h2 class="text-lg font-bold text-[#103221]">Итог checkout</h2>
|
||
<ul class="mt-3 space-y-2 text-sm text-[#214735]">
|
||
<li class="flex items-center justify-between">
|
||
<span>Позиция</span>
|
||
<span class="font-semibold">{{ productName || 'Не указано' }}</span>
|
||
</li>
|
||
<li class="flex items-center justify-between">
|
||
<span>Количество</span>
|
||
<span class="font-semibold">{{ quantity }}</span>
|
||
</li>
|
||
<li class="flex items-center justify-between">
|
||
<span>Цвет</span>
|
||
<span class="font-semibold">{{ color }}</span>
|
||
</li>
|
||
</ul>
|
||
<div class="mt-4 rounded-xl bg-[#139957]/10 p-3 text-sm text-[#174631]">
|
||
Оценочный объём: <span class="font-bold">{{ calculatedVolume }}</span>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="success" class="alert alert-success mx-auto max-w-4xl">{{ success }}</div>
|
||
<div v-if="errorMessage" class="alert alert-error">{{ errorMessage }}</div>
|
||
</section>
|
||
</template>
|