diff --git a/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx b/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx index b15c060..a8310d4 100644 --- a/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx +++ b/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx @@ -45,6 +45,8 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => { const [text, setText] = useState(""); const [adress, setAdress] = useState(""); const [screenHeight, setScreenHeight] = useState(window.innerHeight); + const [emailError, setEmailError] = useState(""); + const [phoneError, setPhoneError] = useState(""); const fireOnce = useRef(true); const [fire, setFire] = useState(false); @@ -200,12 +202,66 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => { const minDigits = isRussianNumber ? 11 : 10; const isPhoneValid = phone.trim().length === 0 || digitsOnly.length >= minDigits; - // Проверяем валидность email - не должен быть пустым - const isEmailValid = email.trim().length === 0; + // Проверяем валидность email - должен быть заполнен и соответствовать формату + const validateEmail = (emailValue: string) => { + if (emailValue.trim().length === 0) return false; + + // Проверяем наличие @ и . + const atIndex = emailValue.indexOf("@"); + const dotIndex = emailValue.lastIndexOf("."); + + if (atIndex === -1 || dotIndex === -1) return false; + + // Точка должна быть после @ + if (dotIndex <= atIndex) return false; + + // Между @ и . должно быть минимум 3 символа + const domainPart = emailValue.substring(atIndex + 1, dotIndex); + if (domainPart.length < 3) return false; + + // После точки должно быть минимум 2 символа + const tldPart = emailValue.substring(dotIndex + 1); + if (tldPart.length < 2) return false; + + return true; + }; + + const isEmailValid = validateEmail(email); // Обработчик изменения телефона const handlePhoneChange = (newPhone: string) => { setPhone(newPhone); + // Очищаем ошибку если поле стало пустым + if (newPhone.trim().length === 0) { + setPhoneError(""); + } + }; + + // Обработчик изменения email + const handleEmailChange = (newEmail: string) => { + setEmail(newEmail); + // Очищаем ошибку если поле стало пустым + if (newEmail.trim().length === 0) { + setEmailError(""); + } + }; + + // Обработчик потери фокуса для email + const handleEmailBlur = () => { + if (email.trim().length > 0 && !validateEmail(email)) { + setEmailError(t("Please enter a valid email")); + } else { + setEmailError(""); + } + }; + + // Обработчик потери фокуса для телефона + const handlePhoneBlur = () => { + if (phone.trim().length > 0 && !isPhoneValid) { + setPhoneError(t("Please enter a valid phone number")); + } else { + setPhoneError(""); + } }; return ( @@ -281,13 +337,17 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => { name={name} setName={setName} email={email} - setEmail={setEmail} + setEmail={handleEmailChange} phone={phone} - setPhone={setPhone} + setPhone={handlePhoneChange} text={text} setText={setText} adress={adress} setAdress={setAdress} + emailError={emailError} + phoneError={phoneError} + onEmailBlur={handleEmailBlur} + onPhoneBlur={handlePhoneBlur} crutch={{ disableEmail: isDisableEmail, }} diff --git a/lib/components/ViewPublicationPage/ContactForm/Inputs/Inputs.tsx b/lib/components/ViewPublicationPage/ContactForm/Inputs/Inputs.tsx index 49e9bce..b4d2f63 100644 --- a/lib/components/ViewPublicationPage/ContactForm/Inputs/Inputs.tsx +++ b/lib/components/ViewPublicationPage/ContactForm/Inputs/Inputs.tsx @@ -13,13 +13,17 @@ type InputsProps = { name: string; setName: Dispatch>; email: string; - setEmail: Dispatch>; + setEmail: (email: string) => void; phone: string; - setPhone: Dispatch>; + setPhone: (phone: string) => void; text: string; setText: Dispatch>; adress: string; setAdress: Dispatch>; + emailError?: string; + phoneError?: string; + onEmailBlur?: () => void; + onPhoneBlur?: () => void; crutch: { disableEmail: boolean; }; @@ -39,6 +43,10 @@ export const Inputs = ({ setText, adress, setAdress, + emailError, + phoneError, + onEmailBlur, + onPhoneBlur, crutch, }: InputsProps) => { const { settings } = useQuizStore(); @@ -64,11 +72,13 @@ export const Inputs = ({ onChange={({ target }) => { setEmail(target.value.replaceAll(/\s/g, "")); }} + onBlur={onEmailBlur} id={email} title={FC["email"].innerText || `${t("Enter")} Email`} desc={FC["email"].text || "Email"} Icon={EmailIcon} type="email" + error={emailError} /> ); const Phone = ( @@ -77,12 +87,14 @@ export const Inputs = ({ onChangePhone={(phone: string) => { setPhone(phone); }} + onBlur={onPhoneBlur} value={phone} id={phone} title={FC["phone"].innerText || `${t("Enter")} ${t("Phone number").toLowerCase()}`} desc={FC["phone"].text || t("Phone number")} Icon={PhoneIcon} isPhone={true} + error={phoneError} /> ); const Text = ( diff --git a/public/locales/ru.json b/public/locales/ru.json index 4994e78..d346874 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -56,5 +56,8 @@ "Step": "Шаг", "questions are not ready yet": "Вопросы для аудитории ещё не созданы. Пожалуйста, подождите", "Add your image": "Добавьте своё изображение", - "select emoji": "выберите смайлик" + "select emoji": "выберите смайлик", + "Please complete the phone number": "Пожалуйста, завершите номер телефона", + "Please enter a valid email": "Пожалуйста, введите корректную почту", + "Please enter a valid phone number": "Пожалуйста, введите корректный номер телефона" }