216 lines
6.2 KiB
Vue
216 lines
6.2 KiB
Vue
<template>
|
|
<form v-if="checkoutContacts" 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
|
|
>
|
|
<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>
|
|
|
|
<div v-if="errors?.name" style="color: #ff6467">
|
|
{{ errors?.name }}
|
|
</div>
|
|
</div>
|
|
|
|
<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
|
|
>
|
|
<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?.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
|
|
>
|
|
<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"
|
|
type="submit"
|
|
:disabled="errors && Object.keys(errors).length > 0"
|
|
/>
|
|
</form>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { useCheckout } from '~/composables/useCheckout'
|
|
|
|
const { checkoutContacts, setCheckoutContacts, nextStep } = useCheckout()
|
|
|
|
const { errors, handleSubmit, defineField } = useForm({
|
|
initialValues: {
|
|
name: checkoutContacts.value.name,
|
|
surname: checkoutContacts.value.surname,
|
|
phone: checkoutContacts.value.phone,
|
|
email: checkoutContacts.value.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) => {
|
|
setCheckoutContacts(values)
|
|
nextStep()
|
|
})
|
|
|
|
definePageMeta({
|
|
layout: 'checkout',
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@use '~/assets/scss/utils' as *;
|
|
|
|
.contacts {
|
|
margin-inline: auto;
|
|
max-width: 400px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
|
|
@include mobile {
|
|
padding-inline: 10px;
|
|
}
|
|
}
|
|
</style>
|