'use client' import styles from '@/app/styles/module/login.module.scss'; import { ChangeEvent, useActionState, useEffect, useRef, useState } from 'react'; import { registration, FormState } from '@/app/actions/auth'; import PhoneInput from '@/app/ui/inputs/phone-input'; import Link from 'next/link'; import { useTranslations } from 'next-intl'; import { IconEye } from '@/app/ui/icons/icons'; import { getSignupFormSchema } from '@/app/actions/definitions'; import { useSearchParams } from 'next/navigation'; import * as z from 'zod' import ConfirmMailModalWindow from '@/app/ui/forms/confirm-mail-modal-window'; import { fetchINN } from '@/app/actions/action'; import { useDebouncedCallback } from 'use-debounce'; export default function RegisterForm() { const searchParams = useSearchParams(); const referralCode = searchParams.get('ref'); const [state, formAction, isPending] = useActionState( registration, undefined, ); const t = useTranslations('Login-register-form'); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [formState, setFormState] = useState(undefined); const [showMailConfirmWindow, setShowMailConfirmWindow] = useState(false); const passwordRef = useRef(null); const [accountType, setAccountType] = useState<'b2c' | 'b2b'>('b2c'); useEffect(() => { setFormState(state); if (state?.mailConfirm) { setShowMailConfirmWindow(true); } }, [state]); const debouncedFetchINN = useDebouncedCallback( async (value) => { const response = await fetchINN(value); if (response.companyName) { setFormState({ ...formState, previousState: { ...formState?.previousState, companyName: response.companyName }, error: { ...formState?.error, companyName: '' } }); } else { setFormState({ ...formState, previousState: { companyName: response.companyName }, error: { ...formState?.error, companyName: '', inn: 'inn-invalid' } }); } }, 500 ); function showPassowrd(target: 'password' | 'confirm-password') { if (target === 'password') { setShowPassword(!showPassword); } else { setShowConfirmPassword(!showConfirmPassword); } } type SignupFormSchema = Awaited>; const [signupFormSchema, setSignupFormSchema] = useState(null); useEffect(() => { let isMounted = true; const loadSchema = async () => { const result = await getSignupFormSchema(accountType); if (isMounted) { setSignupFormSchema(result); } }; loadSchema(); return () => { isMounted = false; }; }, [accountType]); async function validateField( fieldName: string, value: string, ) { switch (fieldName) { case 'confirm_password': const baseSchema = signupFormSchema?.shape.confirm_password; if (!baseSchema) { return { success: true, data: value }; } const baseResult = baseSchema.safeParse(value); if (!baseResult.success) { return baseResult; } const currentPassword = passwordRef.current?.value || ''; if (value !== currentPassword) { return { success: false, error: new z.ZodError([ { code: z.ZodIssueCode.custom, message: 'repeat-password', path: ['confirm_password'] } ]) }; } return { success: true, data: value }; case 'email': case 'fullName': case 'phone': case 'referralCode': case 'password': case 'companyName': case 'agree': case 'inn': const schema = signupFormSchema?.shape[fieldName]; if (!schema) { return { success: true, data: value }; } if (fieldName === 'phone') { return schema.safeParse(value.replace(/[-\(\)\s]/g, '')); } if (fieldName === 'companyName' && accountType === 'b2c') { return { success: true, data: value }; } if (fieldName === 'referralCode') { return { success: true, data: value }; } return schema.safeParse(value); default: throw new Error(`Unknown field: ${fieldName}`); } } async function onChangeHandler(e: ChangeEvent): Promise { const fieldName = e.target.name; if (fieldName !== 'phone') { e.target.value = e.target.value .replace(/([^a-zA-Zа-яёА-ЯЁ0-9@.!#$%&"'*+/=?^_{|}~\-\s])/g, '') .replace(/\s+/g, ' '); } if (fieldName === 'inn') { const currentValue = e.target.value; const cleanedValue = currentValue.replace(/([^0-9])/g, ''); if (cleanedValue.length > 10) { e.target.value = cleanedValue.slice(0, 10); debouncedFetchINN(e.target.value); } else { e.target.value = cleanedValue; } if (cleanedValue.length === 10) { debouncedFetchINN(cleanedValue); } else { if (formState) { setFormState({ ...formState, previousState: { ...formState?.previousState, companyName: '' }, error: { ...formState?.error, companyName: '', inn: '' } }); } } } const validatedField = await validateField(fieldName, e.target.value); if (validatedField.success) { setFormState(prevState => { if (!prevState?.error || !prevState?.error[fieldName]) { return prevState; } const { [fieldName]: _, ...newError } = prevState.error; return { ...prevState, error: newError }; }); } } function switchRegistrationTypeHandler(e: React.MouseEvent, type: 'b2c' | 'b2b') { e.preventDefault(); setAccountType(type); if (formState?.previousState) { setFormState({ ...formState, previousState: { ...formState.previousState, companyName: '', inn: '' }, error: { ...formState.error, companyName: '', inn: '' } }); } } return ( <> {showMailConfirmWindow && (
{ setShowMailConfirmWindow(false); }} > { setShowMailConfirmWindow(false) }} />
)}
{ formAction(e); }} autoComplete="off" >
{formState?.error?.fullName && (

{ formState?.error?.fullName.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
{accountType === 'b2b' ? ( <>
{formState?.error?.inn && (

{ formState?.error?.inn.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
{formState?.error?.companyName && (

{ formState?.error?.companyName.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
) : (
{ e.target.value = e.target.value.toLocaleLowerCase(); onChangeHandler(e) }} /> {formState?.error?.referralCode && (

{ formState?.error?.referralCode.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
) }
{ e.target.value = e.target.value.toLocaleLowerCase(); onChangeHandler(e) }} autoComplete="off" /> {formState?.error?.email && (

{ formState?.error?.email.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
{formState?.error?.phone && (

{ formState?.error?.phone.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
{formState?.error?.password && (

{ formState?.error?.password.split('&').map((e, index) => { return ( {t(e)}
) }) }

)}
{formState?.error?.confirm_password && (

{t(formState?.error?.confirm_password)}

)}
{formState?.error?.agree && (

{t(formState?.error?.agree)}

)} {formState?.error?.server && (

{t(formState?.error?.server)}

)}
) }