This commit is contained in:
@@ -1,97 +1,197 @@
|
||||
<template>
|
||||
<div class="contacts">
|
||||
<UInput
|
||||
v-model="name"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
class="relative"
|
||||
>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
name
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
<form class="contacts" @submit.prevent="onSubmit">
|
||||
<div>
|
||||
<UInput
|
||||
id="name"
|
||||
v-model="name"
|
||||
v-bind="nameAttrs"
|
||||
name="name"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
:invalid="Boolean(errors.name)"
|
||||
:help="errors.name"
|
||||
class="relative w-100"
|
||||
:color="errors.name ? 'error' : 'neutral'"
|
||||
highlight
|
||||
autofocus
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">Имя</span>
|
||||
</label>
|
||||
</UInput>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
name
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">Имя</span>
|
||||
</label>
|
||||
</UInput>
|
||||
|
||||
<UInput
|
||||
v-model="surname"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
class="relative"
|
||||
>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
surname
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">Фамилия</span>
|
||||
</label>
|
||||
</UInput>
|
||||
<div v-if="errors?.name" style="color: #ff6467">
|
||||
{{ errors?.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UInput
|
||||
v-model="phone"
|
||||
v-maska="'+7 (###) ###-##-##'"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
class="relative"
|
||||
>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
phone
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
<div>
|
||||
<UInput
|
||||
id="surname"
|
||||
v-model="surname"
|
||||
v-bind="surnameAttrs"
|
||||
name="surname"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
:invalid="Boolean(errors.surname)"
|
||||
:help="errors.surname"
|
||||
class="relative w-100"
|
||||
:color="errors.surname ? 'error' : 'neutral'"
|
||||
highlight
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">телефон</span>
|
||||
</label>
|
||||
</UInput>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
surname
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">Фамилия</span>
|
||||
</label>
|
||||
</UInput>
|
||||
|
||||
<UInput
|
||||
v-model="email"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
class="relative"
|
||||
trailing-icon="i-lucide-at-sign"
|
||||
>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
email
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
<div v-if="errors?.surname" style="color: #ff6467">
|
||||
{{ errors?.surname }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UInput
|
||||
id="phone"
|
||||
v-model="phone"
|
||||
v-bind="phoneAttrs"
|
||||
v-maska="'+7 (###) ###-##-##'"
|
||||
name="phone"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
:invalid="Boolean(errors.phone)"
|
||||
:help="errors.phone"
|
||||
class="relative w-100"
|
||||
:color="errors.phone ? 'error' : 'neutral'"
|
||||
highlight
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">email</span>
|
||||
</label>
|
||||
</UInput>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
phone
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">телефон</span>
|
||||
</label>
|
||||
</UInput>
|
||||
|
||||
<div v-if="errors?.phone" style="color: #ff6467">
|
||||
{{ errors?.phone }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UInput
|
||||
id="email"
|
||||
v-model="email"
|
||||
v-bind="emailAttrs"
|
||||
name="email"
|
||||
size="xl"
|
||||
placeholder=" "
|
||||
:ui="{ base: 'peer' }"
|
||||
class="relative w-100"
|
||||
trailing-icon="i-lucide-at-sign"
|
||||
:invalid="Boolean(errors.email)"
|
||||
:help="errors.email"
|
||||
:color="errors.email ? 'error' : 'neutral'"
|
||||
highlight
|
||||
>
|
||||
<label
|
||||
class="pointer-events-none absolute left-3 text-base transition-all peer-focus:-top-3 peer-focus:text-highlighted peer-focus:text-sm peer-focus:font-medium" :class="[
|
||||
email
|
||||
? '-top-3 text-sm text-highlighted font-medium'
|
||||
: 'top-3 text-dimmed peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-dimmed',
|
||||
]"
|
||||
>
|
||||
<span class="inline-flex bg-default px-1">email</span>
|
||||
</label>
|
||||
</UInput>
|
||||
|
||||
<div v-if="errors?.email" style="color: #ff6467">
|
||||
{{ errors?.email }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UButton
|
||||
size="xl"
|
||||
label="продолжить"
|
||||
class="justify-center text-center"
|
||||
@click="nextStep"
|
||||
type="submit"
|
||||
:disabled="errors && Object.keys(errors).length > 0"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useCheckout } from '../../composables/useCheckout'
|
||||
|
||||
const name = ref('')
|
||||
const surname = ref('')
|
||||
const phone = ref('')
|
||||
const email = ref('')
|
||||
const { setContacts, nextStep } = useCheckout()
|
||||
|
||||
const { nextStep } = useCheckout()
|
||||
const { errors, handleSubmit, defineField } = useForm({
|
||||
initialValues: {
|
||||
name: '',
|
||||
surname: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
},
|
||||
validationSchema: {
|
||||
name(value: string) {
|
||||
if (!value)
|
||||
return 'Укажите имя'
|
||||
if (value.trim().length < 2)
|
||||
return 'Минимум 2 символа'
|
||||
return true
|
||||
},
|
||||
surname(value: string) {
|
||||
if (!value)
|
||||
return 'Укажите фамилию'
|
||||
if (value.trim().length < 2)
|
||||
return 'Минимум 2 символа'
|
||||
return true
|
||||
},
|
||||
phone(value: string) {
|
||||
if (!value)
|
||||
return 'Укажите телефон'
|
||||
const digits = (value || '').replace(/\D/g, '')
|
||||
if (digits.length < 11)
|
||||
return 'Введите корректный телефон'
|
||||
return true
|
||||
},
|
||||
email(value: string) {
|
||||
if (!value)
|
||||
return 'Укажите email'
|
||||
const re = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/
|
||||
if (!re.test(value))
|
||||
return 'Введите корректный email'
|
||||
return true
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const [name, nameAttrs] = defineField('name')
|
||||
const [surname, surnameAttrs] = defineField('surname')
|
||||
const [phone, phoneAttrs] = defineField('phone')
|
||||
const [email, emailAttrs] = defineField('email')
|
||||
|
||||
const onSubmit = handleSubmit((values) => {
|
||||
setContacts(values)
|
||||
nextStep()
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
layout: 'checkout',
|
||||
|
||||
@@ -1,12 +1,119 @@
|
||||
<template>
|
||||
<UButton label="СОздать ОредЕр" @click="createOrder" />
|
||||
<div class="summary">
|
||||
<div class="summary__info">
|
||||
<h3>в заказе • {{ cart?.line_items?.length }} шт</h3>
|
||||
|
||||
<div class="summary__items">
|
||||
<div
|
||||
v-for="cartItem in cart?.line_items"
|
||||
:key="cartItem.variation_id"
|
||||
>
|
||||
<SummaryCartItem :summary-cart-item="cartItem" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h3 class="d-flex gap-1 text-center align-items-center">
|
||||
Yandex
|
||||
|
||||
<UButton
|
||||
size="sm"
|
||||
class="text-muted-foreground"
|
||||
variant="ghost"
|
||||
icon="i-ph-pencil-simple-line"
|
||||
@click="onEditDelivery"
|
||||
/>
|
||||
</h3>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h3 class="d-flex gap-1 text-center align-items-center">
|
||||
Получатель
|
||||
|
||||
<UButton
|
||||
size="sm"
|
||||
class="text-muted-foreground"
|
||||
variant="ghost"
|
||||
icon="i-ph-pencil-simple-line"
|
||||
@click="onEditContacts"
|
||||
/>
|
||||
</h3>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-user" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.name }} {{ contacts?.surname }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-envelope-simple" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.email }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-ph-phone" class="text-muted-foreground" />
|
||||
<span>{{ contacts?.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UButton label="СОздать ОредЕр" @click="createOrder" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { IBspb } from '~/server/shared/types/bspb'
|
||||
import SummaryCartItem from '../../components/cart/SummaryCartItem.vue'
|
||||
|
||||
const { cart } = useCart()
|
||||
const { contacts } = useCheckout()
|
||||
|
||||
function onEditDelivery() {
|
||||
console.log('pizda')
|
||||
}
|
||||
|
||||
function onEditContacts() {
|
||||
console.log('pizda')
|
||||
}
|
||||
|
||||
const createOrder = async () => {
|
||||
const { data } = await useFetch<IBspb>('/api/bspb')
|
||||
const { data } = await useFetch<IBspb>('/api/bspb', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
order: {
|
||||
typeRid: 'Purchase',
|
||||
amount: 100,
|
||||
currency: 'RUB',
|
||||
hppRedirectUrl: `${import.meta.env.VITE_BASE_URL}/cart`,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const redirectUrl = `${data?.value?.order?.hppUrl}?orderId=${data?.value?.order?.id}&password=${data.value?.order?.password}`
|
||||
window.open(redirectUrl, '_blank')
|
||||
@@ -17,6 +124,27 @@ definePageMeta({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.summary {
|
||||
max-width: 1200px;
|
||||
margin-inline: auto;
|
||||
padding-inline: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
&__items {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user