fix: update form

This commit is contained in:
2025-06-16 16:26:23 +03:00
parent d53c5606ff
commit 39d4c3c362
30 changed files with 653 additions and 125 deletions

View File

@@ -0,0 +1,41 @@
.Container {
position: relative;
}
.Phone {
width: 100%;
position: relative;
z-index: 2;
@include iftablet{
}
@include iflaptop{
padding-left: rem(16px);
}
@include ifdesktop{
padding-left: rem(32px);
}
}
.Button {
position: absolute;
z-index: 3;
right: rem(2px);
top: calc(50% - 1.2rem);
min-height: calc(100% - .25rem);
@include iftablet{
top: calc(50% - 1.2rem);
right: rem(3px);
}
@include iflaptop{
top: calc(50% - 1.4rem);
right: rem(4px);
}
@include ifdesktop{
top: calc(50% - 1.6rem);
right: rem(2px);
}
}

View File

@@ -0,0 +1,84 @@
'use client';
import s from './advanced-phone-input.module.scss';
import { clsx } from 'clsx';
import { Button, PhoneInput } from '@shared/ui';
import { z } from 'zod';
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import toast from 'react-hot-toast';
import { sendFormFn } from '@shared/api/api.service';
import { isValidPhoneNumber } from 'libphonenumber-js/min';
type AdvancedPhoneInputProps = {
containerClassName?: string;
};
const FormSchema = z.object({
phone: z.string().refine(isValidPhoneNumber, 'Некорректный номер телефона'),
});
type TForm = z.infer<typeof FormSchema>;
const defaultValues = {
phone: '',
};
export default function AdvancedPhoneInput({
containerClassName,
}: AdvancedPhoneInputProps) {
const {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
resolver: zodResolver(FormSchema),
defaultValues,
});
const onSubmit = async (data: TForm) => {
const payload = {
...data,
form: 'offer-request-form-desktop',
};
try {
await sendFormFn(payload);
toast.success('Заявка на консультацию принята');
reset(defaultValues);
} catch (e) {
toast.error('Ошибка при отправке заявки...', {
duration: 3000,
});
}
};
return (
<form
className={clsx(containerClassName, s.Container)}
onSubmit={handleSubmit(onSubmit)}
>
<Controller
control={control}
name={'phone'}
render={({ field }) => (
<PhoneInput
{...field}
className={s.Phone}
placeholder={'+7 (999) 123-45-67'}
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
error={errors && errors.phone?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Button className={s.Button} variant='orange'>
Отправить заявку
</Button>
</form>
);
}

View File

@@ -0,0 +1 @@
export { default as AdvancedPhoneInput } from './advanced-phone-input';

View File

@@ -1,7 +1,7 @@
'use client';
import s from './styles.module.scss';
import { Button, Input } from '@shared/ui';
import { Button, Input, PhoneInput } from '@shared/ui';
import Image from 'next/image';
import toast from 'react-hot-toast';
import { Controller, useForm } from 'react-hook-form';
@@ -10,10 +10,16 @@ import { z } from 'zod';
import bgForm from '@public/images/bg-form.jpg';
import { sendFormFn } from '@shared/api/api.service';
import { isValidPhoneNumber } from 'libphonenumber-js/min';
const FormSchema = z.object({
name: z.string().min(3),
phone: z.string(),
name: z
.string()
.min(3, { message: 'Поле должно содержать не менее 3-х букв' })
.regex(/^[A-Za-zА-Яа-яЁё]+(?:[ '-][A-Za-zА-Яа-яЁё]+)*$/, {
message: 'Поле содержит некорректные символы',
}),
phone: z.string().refine(isValidPhoneNumber, 'Некорректный номер телефона'),
});
type TForm = z.infer<typeof FormSchema>;
@@ -27,6 +33,7 @@ export default function ContactsForm() {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
mode: 'onSubmit',
@@ -75,18 +82,33 @@ export default function ContactsForm() {
control={control}
name={'name'}
render={({ field }) => (
<Input {...field} type='text' placeholder='Ваше имя' fullWidth />
<Input
{...field}
placeholder={'Ваше имя'}
fullWidth
onChange={(e) => {
clearErrors('name');
field.onChange(e);
}}
error={errors && errors.name?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Controller
control={control}
name={'phone'}
render={({ field }) => (
<Input
<PhoneInput
{...field}
type='text'
placeholder='+7 (999) 123 45 67'
placeholder={'+7 (999) 123-45-67'}
fullWidth
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
error={errors && errors.phone?.message}
errorTextColor={'#ff9191'}
/>
)}
/>

View File

@@ -1,7 +1,7 @@
'use client';
import s from './styles.module.scss';
import { Button, Input, Mark, TextArea } from '@shared/ui';
import { Button, Input, Mark, PhoneInput, TextArea } from '@shared/ui';
import toast from 'react-hot-toast';
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
@@ -9,11 +9,19 @@ import { z } from 'zod';
import man from '@public/images/footer-man.png';
import { sendFormFn } from '@shared/api/api.service';
import { isValidPhoneNumber } from 'libphonenumber-js/min';
const FormSchema = z.object({
name: z.string().min(3),
phone: z.string(),
message: z.string(),
name: z
.string()
.min(3, { message: 'Поле должно содержать не менее 3-х букв' })
.regex(/^[A-Za-zА-Яа-яЁё]+(?:[ '-][A-Za-zА-Яа-яЁё]+)*$/, {
message: 'Поле содержит некорректные символы',
}),
phone: z.string().refine(isValidPhoneNumber, 'Некорректный номер телефона'),
message: z
.string()
.min(21, { message: 'Оставьте сообщение мин. 20 символов' }),
});
type TForm = z.infer<typeof FormSchema>;
@@ -28,6 +36,7 @@ export default function FooterForm() {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
mode: 'onSubmit',
@@ -67,6 +76,12 @@ export default function FooterForm() {
variant='ghost'
placeholder={'Ваше имя'}
fullWidth
onChange={(e) => {
clearErrors('name');
field.onChange(e);
}}
error={errors && errors.name?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
@@ -74,11 +89,17 @@ export default function FooterForm() {
control={control}
name={'phone'}
render={({ field }) => (
<Input
<PhoneInput
{...field}
variant='ghost'
placeholder={'+7 999 1234567'}
placeholder={'+7 (999) 123-45-67'}
fullWidth
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
error={errors && errors.phone?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
@@ -94,6 +115,8 @@ export default function FooterForm() {
id='story'
name='story'
rows={6}
error={errors && errors.message?.message}
errorTextColor={'#ff9191'}
/>
)}
/>

View File

@@ -4,3 +4,4 @@ export { LicenseForm } from './license-form';
export { LicenseSlider } from './license-slider';
export { OfferForm } from './offer-form';
export { OfferRequestForm } from './offer-request';
export { AdvancedPhoneInput } from './advanced-phone-input';

View File

@@ -1,7 +1,7 @@
'use client';
import s from './styles.module.scss';
import { Button, Input } from '@shared/ui';
import { Button, Input, PhoneInput } from '@shared/ui';
import Image from 'next/image';
import toast from 'react-hot-toast';
@@ -10,11 +10,18 @@ import { z } from 'zod';
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { sendFormFn } from '@shared/api/api.service';
import { isValidPhoneNumber } from 'libphonenumber-js/min';
const FormSchema = z.object({
name: z.string().min(3),
phone: z.string(),
name: z
.string()
.min(3, { message: 'Поле должно содержать не менее 3-х букв' })
.regex(/^[A-Za-zА-Яа-яЁё]+(?:[ '-][A-Za-zА-Яа-яЁё]+)*$/, {
message: 'Поле содержит некорректные символы',
}),
phone: z.string().refine(isValidPhoneNumber, 'Некорректный номер телефона'),
});
type TForm = z.infer<typeof FormSchema>;
const defaultValues = {
@@ -27,6 +34,7 @@ export default function LicenseForm() {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
mode: 'onSubmit',
@@ -77,14 +85,34 @@ export default function LicenseForm() {
control={control}
name={'name'}
render={({ field }) => (
<Input {...field} placeholder={'Ваше имя'} fullWidth />
<Input
{...field}
placeholder={'Ваше имя'}
fullWidth
onChange={(e) => {
clearErrors('name');
field.onChange(e);
}}
error={errors && errors.name?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Controller
control={control}
name={'phone'}
render={({ field }) => (
<Input {...field} placeholder={'+7 (999) 123 45 67'} fullWidth />
<PhoneInput
{...field}
placeholder={'+7 (999) 123-45-67'}
fullWidth
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
error={errors && errors.phone?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Button variant='orange' fullWidth>

View File

@@ -30,10 +30,9 @@ export default function OfferForm() {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
mode: 'onSubmit',
reValidateMode: 'onBlur',
resolver: zodResolver(FormSchema),
defaultValues,
});
@@ -66,6 +65,11 @@ export default function OfferForm() {
className={s.Unit}
type='text'
placeholder='Ваше имя'
error={errors && errors.name?.message}
onChange={(e) => {
clearErrors('name');
field.onChange(e);
}}
/>
)}
/>
@@ -78,6 +82,11 @@ export default function OfferForm() {
className={s.Unit}
type='text'
placeholder='+7 999 123-45-67'
error={errors && errors.phone?.message}
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
/>
)}
/>

View File

@@ -69,7 +69,7 @@
position: relative;
display: flex;
flex-direction: column;
gap: rem(12px);
gap: rem(20px);
z-index: 2;
max-width: rem(400px);
@include iftablet{

View File

@@ -1,7 +1,7 @@
'use client';
import s from './styles.module.scss';
import { AdvancedPhoneInput, Button, Input } from '@shared/ui';
import { Button, Input, PhoneInput } from '@shared/ui';
import Image from 'next/image';
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
@@ -9,12 +9,18 @@ import { z } from 'zod';
import toast from 'react-hot-toast';
import bgForm from '@public/images/bg-form.jpg';
import { useState } from 'react';
import { AdvancedPhoneInput } from '@/widgets';
import { sendFormFn } from '@shared/api/api.service';
import { isValidPhoneNumber } from 'libphonenumber-js/min';
const FormSchema = z.object({
name: z.string().min(3),
phone: z.string(),
name: z
.string()
.min(3, { message: 'Поле должно содержать не менее 3-х букв' })
.regex(/^[A-Za-zА-Яа-яЁё]+(?:[ '-][A-Za-zА-Яа-яЁё]+)*$/, {
message: 'Поле содержит некорректные символы',
}),
phone: z.string().refine(isValidPhoneNumber, 'Некорректный номер телефона'),
});
type TForm = z.infer<typeof FormSchema>;
@@ -28,6 +34,7 @@ export default function OfferRequest() {
handleSubmit,
control,
reset,
clearErrors,
formState: { errors },
} = useForm<TForm>({
mode: 'onSubmit',
@@ -36,12 +43,10 @@ export default function OfferRequest() {
defaultValues,
});
const [inputPhone, setInputPhone] = useState('');
const onSubmitForm = async (data: TForm) => {
const onSubmit = async (data: TForm) => {
const payload = {
...data,
form: 'offer-request-form',
form: 'offer-request-form-mobile',
};
try {
@@ -55,23 +60,6 @@ export default function OfferRequest() {
}
};
const onSubmitPhone = async (phone: string) => {
const payload = {
phone: phone,
form: 'offer-request-form',
};
try {
await sendFormFn(payload);
toast.success('Заявка на консультацию принята');
setInputPhone('');
} catch (e) {
toast.error('Ошибка при отправке заявки...', {
duration: 3000,
});
}
};
return (
<div className={s.Form}>
<Image
@@ -88,28 +76,40 @@ export default function OfferRequest() {
<h3 className={s.Title}>Оставьте заявку на бесплатную консультацию</h3>
</div>
<div className={s.PanelRight}>
<AdvancedPhoneInput
value={inputPhone}
onChange={(e) => setInputPhone(e.target.value)}
onClick={() => onSubmitPhone(inputPhone)}
containerClassName={s.AdvPhoneInput}
text='Отправить заявку'
placeholder={'+7 (999) 123 45 67'}
/>
<AdvancedPhoneInput containerClassName={s.AdvPhoneInput} />
<form className={s.MobileBtns} onSubmit={handleSubmit(onSubmitForm)}>
<form className={s.MobileBtns} onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name={'name'}
render={({ field }) => (
<Input {...field} placeholder='Ваше имя' fullWidth />
<Input
{...field}
placeholder='Ваше имя'
fullWidth
onChange={(e) => {
clearErrors('name');
field.onChange(e);
}}
error={errors && errors.name?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Controller
control={control}
name={'phone'}
render={({ field }) => (
<Input {...field} placeholder='+7 999 123 45 67' fullWidth />
<PhoneInput
{...field}
placeholder='+7 (999) 123-45-67'
onChange={(e) => {
clearErrors('phone');
field.onChange(e);
}}
error={errors && errors.phone?.message}
errorTextColor={'#ff9191'}
/>
)}
/>
<Button variant='orange' fullWidth>