feat: UI changes
This commit is contained in:
@@ -266,6 +266,7 @@ TEXT,
|
|||||||
'module_tgshop_customer_notification_template' => <<<TEXT
|
'module_tgshop_customer_notification_template' => <<<TEXT
|
||||||
Спасибо за Ваш заказ в магазине *{store_name}*
|
Спасибо за Ваш заказ в магазине *{store_name}*
|
||||||
|
|
||||||
|
*Номер заказа* \#{order_id}
|
||||||
*Сумма заказа:* {total}
|
*Сумма заказа:* {total}
|
||||||
*Дата оформления:* {created_at}
|
*Дата оформления:* {created_at}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class Email implements ValidationRuleInterface
|
|||||||
{
|
{
|
||||||
$email = $input[$field] ?? '';
|
$email = $input[$field] ?? '';
|
||||||
|
|
||||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
if ($email && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
$fail('Email is not valid');
|
$fail('Email is not valid');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ class OrderHandler
|
|||||||
public function store(Request $request): JsonResponse
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->orderCreateService->create($request->json(), [
|
$order = $this->orderCreateService->create($request->json(), [
|
||||||
'ip' => $request->getClientIp(),
|
'ip' => $request->getClientIp(),
|
||||||
'user_agent' => $request->getUserAgent(),
|
'user_agent' => $request->getUserAgent(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_CREATED);
|
return new JsonResponse([
|
||||||
|
'data' => $order,
|
||||||
|
], Response::HTTP_CREATED);
|
||||||
} catch (OrderValidationFailedException $exception) {
|
} catch (OrderValidationFailedException $exception) {
|
||||||
return new JsonResponse([
|
return new JsonResponse([
|
||||||
'data' => $exception->getErrorBag()->firstOfAll(),
|
'data' => $exception->getErrorBag()->firstOfAll(),
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace App\Services;
|
|||||||
|
|
||||||
use App\Decorators\OcRegistryDecorator;
|
use App\Decorators\OcRegistryDecorator;
|
||||||
use App\Exceptions\OrderValidationFailedException;
|
use App\Exceptions\OrderValidationFailedException;
|
||||||
|
use Cassandra\Date;
|
||||||
|
use DateTime;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Openguru\OpenCartFramework\Config\Settings;
|
use Openguru\OpenCartFramework\Config\Settings;
|
||||||
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||||
@@ -44,7 +46,7 @@ class OrderCreateService
|
|||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(array $data, array $meta = []): void
|
public function create(array $data, array $meta = []): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->validate($data);
|
$this->validate($data);
|
||||||
@@ -178,6 +180,19 @@ class OrderCreateService
|
|||||||
$orderData['total'] = $cart['total_text'] ?? '';
|
$orderData['total'] = $cart['total_text'] ?? '';
|
||||||
|
|
||||||
$this->sendNotifications($orderData, $data['tgData']);
|
$this->sendNotifications($orderData, $data['tgData']);
|
||||||
|
|
||||||
|
$dateTimeFormatted = '';
|
||||||
|
try {
|
||||||
|
$dateTimeFormatted = (new DateTime($orderData['date_added']))->format('d.m.Y H:i');
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
$this->logger->logException($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $orderData['order_id'],
|
||||||
|
'created_at' => $dateTimeFormatted,
|
||||||
|
'total' => $orderData['total'],
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,7 +235,7 @@ class OrderCreateService
|
|||||||
if ($chatId && $template) {
|
if ($chatId && $template) {
|
||||||
$message = $this->telegramService->prepareMessage($template, $variables);
|
$message = $this->telegramService->prepareMessage($template, $variables);
|
||||||
try {
|
try {
|
||||||
$this->telegramService->sendMessage($chatId, $message);
|
$this->telegramService->sendMessage((int) $chatId, $message);
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$this->logger->error("Telegram sendMessage to owner error. ChatID: $chatId, Message: $message");
|
$this->logger->error("Telegram sendMessage to owner error. ChatID: $chatId, Message: $message");
|
||||||
$this->logger->logException($exception);
|
$this->logger->logException($exception);
|
||||||
@@ -247,10 +262,8 @@ class OrderCreateService
|
|||||||
return [
|
return [
|
||||||
'firstName' => 'required',
|
'firstName' => 'required',
|
||||||
'lastName' => 'required',
|
'lastName' => 'required',
|
||||||
'email' => 'required|email',
|
|
||||||
'phone' => 'required',
|
'phone' => 'required',
|
||||||
'address' => 'required',
|
'email' => 'email',
|
||||||
'comment' => 'required',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
75
spa/package-lock.json
generated
75
spa/package-lock.json
generated
@@ -16,6 +16,7 @@
|
|||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"swiper": "^11.2.10",
|
"swiper": "^11.2.10",
|
||||||
"vue": "^3.5.17",
|
"vue": "^3.5.17",
|
||||||
|
"vue-imask": "^7.6.1",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"vue-tg": "^0.9.0-beta.10"
|
"vue-tg": "^0.9.0-beta.10"
|
||||||
},
|
},
|
||||||
@@ -74,6 +75,18 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime-corejs3": {
|
||||||
|
"version": "7.28.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.3.tgz",
|
||||||
|
"integrity": "sha512-LKYxD2CIfocUFNREQ1yk+dW+8OH8CRqmgatBZYXb+XhuObO8wsDpEoCNri5bKld9cnj8xukqZjxSX8p1YiRF8Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"core-js-pure": "^3.43.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.28.0",
|
"version": "7.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz",
|
||||||
@@ -1410,6 +1423,17 @@
|
|||||||
"url": "https://github.com/sponsors/mesqueeb"
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/core-js-pure": {
|
||||||
|
"version": "3.45.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.45.0.tgz",
|
||||||
|
"integrity": "sha512-OtwjqcDpY2X/eIIg1ol/n0y/X8A9foliaNt1dSK0gV3J2/zw+89FcNG3mPK+N8YWts4ZFUPxnrAzsxs/lf8yDA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/core-js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/crypto-js": {
|
"node_modules/crypto-js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||||
@@ -1590,6 +1614,18 @@
|
|||||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/imask": {
|
||||||
|
"version": "7.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/imask/-/imask-7.6.1.tgz",
|
||||||
|
"integrity": "sha512-sJlIFM7eathUEMChTh9Mrfw/IgiWgJqBKq2VNbyXvBZ7ev/IlO6/KQTKlV/Fm+viQMLrFLG/zCuudrLIwgK2dg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime-corejs3": "^7.24.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"npm": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-what": {
|
"node_modules/is-what": {
|
||||||
"version": "4.1.16",
|
"version": "4.1.16",
|
||||||
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
|
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
|
||||||
@@ -2305,6 +2341,45 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-demi": {
|
||||||
|
"version": "0.14.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
|
||||||
|
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vue-imask": {
|
||||||
|
"version": "7.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-imask/-/vue-imask-7.6.1.tgz",
|
||||||
|
"integrity": "sha512-/5ZVNerI9Dn6gZ/cSCYGiZK4JHdwsEBgHBTRpVwS2U0URxK/Jt5FlQuoL1DhbxC6t4ElcVMWYOvkE2hR8hdt1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"imask": "^7.6.1",
|
||||||
|
"vue-demi": "^0.14.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": ">=2.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-router": {
|
"node_modules/vue-router": {
|
||||||
"version": "4.5.1",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"swiper": "^11.2.10",
|
"swiper": "^11.2.10",
|
||||||
"vue": "^3.5.17",
|
"vue": "^3.5.17",
|
||||||
|
"vue-imask": "^7.6.1",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"vue-tg": "^0.9.0-beta.10"
|
"vue-tg": "^0.9.0-beta.10"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const router = useRouter();
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const isCartBtnShow = computed(() => {
|
const isCartBtnShow = computed(() => {
|
||||||
return route.name !== 'cart' && route.name !== 'checkout';
|
return route.name !== 'cart' && route.name !== 'checkout' && route.name !== 'order_created';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
<input
|
<input
|
||||||
:type="type"
|
:type="type"
|
||||||
:inputmode="inputMode"
|
:inputmode="inputMode"
|
||||||
class="input w-full"
|
class="input input-lg w-full"
|
||||||
:class="error ? 'input-error' : ''"
|
:class="error ? 'input-error' : ''"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
v-model="model"
|
v-model="model"
|
||||||
@input="$emit('clearError')"
|
@input="$emit('clearError')"
|
||||||
|
:maxlength="maxlength"
|
||||||
/>
|
/>
|
||||||
<p v-if="error" class="label">{{ error }}</p>
|
<p v-if="error" class="label">{{ error }}</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -32,6 +33,11 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'text',
|
default: 'text',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
maxlength: {
|
||||||
|
type: Number,
|
||||||
|
default: 1000,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const emits = defineEmits(['clearError']);
|
const emits = defineEmits(['clearError']);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<fieldset class="fieldset mb-0">
|
<fieldset class="fieldset mb-0">
|
||||||
<textarea
|
<textarea
|
||||||
class="input w-full h-30"
|
class="input input-lg w-full h-50"
|
||||||
:class="error ? 'input-error' : ''"
|
:class="error ? 'input-error' : ''"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
v-model="model"
|
v-model="model"
|
||||||
@input="$emit('clearError')"
|
@input="$emit('clearError')"
|
||||||
rows="5"
|
rows="8"
|
||||||
|
:maxlength="maxlength"
|
||||||
/>
|
/>
|
||||||
<p v-if="error" class="label">{{ error }}</p>
|
<p v-if="error" class="label">{{ error }}</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -25,6 +26,11 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
maxlength: {
|
||||||
|
type: Number,
|
||||||
|
default: 1000,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const emits = defineEmits(['clearError']);
|
const emits = defineEmits(['clearError']);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ export const useCheckoutStore = defineStore('checkout', {
|
|||||||
tgData: null,
|
tgData: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
order: null,
|
||||||
|
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
validationErrors: {},
|
validationErrors: {},
|
||||||
}),
|
}),
|
||||||
@@ -50,7 +52,10 @@ export const useCheckoutStore = defineStore('checkout', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.customer.tgData = data;
|
this.customer.tgData = data;
|
||||||
await storeOrder(this.customer);
|
|
||||||
|
const response = await storeOrder(this.customer);
|
||||||
|
this.order = response.data;
|
||||||
|
|
||||||
await window.Telegram.WebApp.HapticFeedback.notificationOccurred('success');
|
await window.Telegram.WebApp.HapticFeedback.notificationOccurred('success');
|
||||||
await useCartStore().getProducts();
|
await useCartStore().getProducts();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.safe-top {
|
.safe-top {
|
||||||
margin-top: calc(var(--tg-content-safe-area-inset-top) + var(--tg-safe-area-inset-top));
|
padding-top: calc(var(--tg-content-safe-area-inset-top) + var(--tg-safe-area-inset-top));
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-pagination-bullets > .swiper-pagination-bullet {
|
.swiper-pagination-bullets > .swiper-pagination-bullet {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="max-w-3xl mx-auto p-4 space-y-6 pb-30 safe-top">
|
<div class="max-w-3xl mx-auto space-y-6 pb-30 safe-top">
|
||||||
<h2 class="text-2xl">
|
<h2 class="text-2xl text-center">
|
||||||
Оформление заказа
|
Оформление заказа
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -10,42 +10,39 @@
|
|||||||
v-model="checkout.customer.firstName"
|
v-model="checkout.customer.firstName"
|
||||||
placeholder="Введите имя"
|
placeholder="Введите имя"
|
||||||
:error="checkout.validationErrors.firstName"
|
:error="checkout.validationErrors.firstName"
|
||||||
|
:maxlength="32"
|
||||||
@clearError="checkout.clearError('firstName')"
|
@clearError="checkout.clearError('firstName')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TgInput
|
<TgInput
|
||||||
v-model="checkout.customer.lastName"
|
v-model="checkout.customer.lastName"
|
||||||
placeholder="Введите фамилию"
|
placeholder="Введите фамилию"
|
||||||
|
:maxlength="32"
|
||||||
:error="checkout.validationErrors.lastName"
|
:error="checkout.validationErrors.lastName"
|
||||||
@clearError="checkout.clearError('lastName')"
|
@clearError="checkout.clearError('lastName')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<IMaskComponent
|
||||||
|
v-model="checkout.customer.phone"
|
||||||
|
type="tel"
|
||||||
|
class="input input-lg w-full"
|
||||||
|
mask="+{7} (000) 000-00-00"
|
||||||
|
placeholder="Введите телефон"
|
||||||
|
:unmask="true"
|
||||||
|
/>
|
||||||
|
|
||||||
<TgInput
|
<TgInput
|
||||||
v-model="checkout.customer.email"
|
v-model="checkout.customer.email"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Введите email"
|
placeholder="Введите email (опционально)"
|
||||||
|
:maxlength="96"
|
||||||
:error="checkout.validationErrors.email"
|
:error="checkout.validationErrors.email"
|
||||||
@clearError="checkout.clearError('email')"
|
@clearError="checkout.clearError('email')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TgInput
|
|
||||||
v-model="checkout.customer.phone"
|
|
||||||
type="tel"
|
|
||||||
placeholder="Введите телефон"
|
|
||||||
:error="checkout.validationErrors.phone"
|
|
||||||
@clearError="checkout.clearError('phone')"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TgInput
|
|
||||||
v-model="checkout.customer.address"
|
|
||||||
placeholder="Адрес доставки"
|
|
||||||
:error="checkout.validationErrors.address"
|
|
||||||
@clearError="checkout.clearError('address')"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TgTextarea
|
<TgTextarea
|
||||||
v-model="checkout.customer.comment"
|
v-model="checkout.customer.comment"
|
||||||
placeholder="Комментарий"
|
placeholder="Комментарий (опционально)"
|
||||||
:error="checkout.validationErrors.comment"
|
:error="checkout.validationErrors.comment"
|
||||||
@clearError="checkout.clearError('comment')"
|
@clearError="checkout.clearError('comment')"
|
||||||
/>
|
/>
|
||||||
@@ -73,6 +70,7 @@ import TgInput from "@/components/Form/TgInput.vue";
|
|||||||
import TgTextarea from "@/components/Form/TgTextarea.vue";
|
import TgTextarea from "@/components/Form/TgTextarea.vue";
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import {computed, ref} from "vue";
|
import {computed, ref} from "vue";
|
||||||
|
import {IMaskComponent} from "vue-imask";
|
||||||
|
|
||||||
const checkout = useCheckoutStore();
|
const checkout = useCheckoutStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|||||||
@@ -1,16 +1,43 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="safe-top max-w-3xl mx-auto p-4 space-y-6 pb-30 flex flex-col items-center h-full justify-center">
|
<div class="safe-top max-w-3xl mx-auto p-4 space-y-6 pb-30 flex flex-col items-center h-full justify-center">
|
||||||
<div class="flex flex-col justify-center items-center">
|
<div class="flex flex-col justify-center items-center px-5">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-20 text-success">
|
<div class="mb-3">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-25 text-success">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-2xl font-bold mb-3">Спасибо за заказ!</p>
|
||||||
|
<p class="text-center mb-4">Ваш заказ успешно оформлен и будет обработан в ближайшее время.</p>
|
||||||
|
|
||||||
|
<ul v-if="checkout.order" class="list w-full bg-base-200 mb-4">
|
||||||
|
<li class="list-row flex justify-between">
|
||||||
|
<div>Номер заказа:</div>
|
||||||
|
<div class="font-bold">#{{ checkout.order.id }}</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="list-row flex justify-between">
|
||||||
|
<div>Дата:</div>
|
||||||
|
<div class="font-bold">{{ checkout.order.created_at }}</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="list-row flex justify-between">
|
||||||
|
<div>Сумма:</div>
|
||||||
|
<div class="font-bold">{{ checkout.order.total }}</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p class="text-xs text-neutral mb-10">
|
||||||
|
Подтверждение отправлено Вам в личных сообщениях.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="text-lg mb-3">Ваш заказ создан!</p>
|
|
||||||
<RouterLink class="btn btn-primary" to="/">На главную</RouterLink>
|
<RouterLink class="btn btn-primary" to="/">На главную</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup>
|
||||||
|
import {useCheckoutStore} from "@/stores/CheckoutStore.js";
|
||||||
|
|
||||||
|
const checkout = useCheckoutStore();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user