From 0e4b7868c991bb6e3e7e0b40523b035f89cd4207 Mon Sep 17 00:00:00 2001 From: nns <278048682+nurdotnet@users.noreply.github.com> Date: Wed, 6 May 2026 11:21:43 +0500 Subject: [PATCH] =?UTF-8?q?feat(forms):=20TextInput=20=D1=81=20type=3Demai?= =?UTF-8?q?l=20=E2=80=94=20=D0=B0=D0=B2=D1=82=D0=BE-pattern=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20TLD-=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раньше явный validateEmail вызывался только в LoginPage и SignupForm. Остальные формы (Counterparties, Employees, SuperAdminOrgCreate, SuperAdminOrgEmployees, SuperAdminSetup) использовали голый , который пропускает «name@domain» без TLD. Сделал общий TextInput строже: если type=email и pattern не задан явно, автоматически проставляется pattern=[^@\s]+@[^@\s]+\.[A-Za-z]{2,} (требует домен верхнего уровня минимум 2 буквы) + title с понятным текстом подсказки. localizeNativeValidation (уже подключён к TextInput через useEffect) переведёт patternMismatch в русское сообщение из title-атрибута. Это покрывает все формы с email-полем единообразно — отдельно править каждую страницу не пришлось. Серверный AuthorizationController + signup тоже проверяют email через свой validateEmail (food-market.web/lib/ validation.ts) — клиент и сервер консистентны. --- src/food-market.web/src/components/Field.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/food-market.web/src/components/Field.tsx b/src/food-market.web/src/components/Field.tsx index 053b894..3527dd2 100644 --- a/src/food-market.web/src/components/Field.tsx +++ b/src/food-market.web/src/components/Field.tsx @@ -36,7 +36,15 @@ export function TextInput(props: InputHTMLAttributes) { useEffect(() => { if (ref.current) localizeNativeValidation(ref.current) }, []) - return + // Email type без явного pattern — добавляем строгий pattern (требует TLD ≥2), + // чтобы name@domain без точки/зоны не проходил. title задаёт текст подсказки; + // localizeNativeValidation подставит его при patternMismatch. + const extraProps: InputHTMLAttributes = {} + if (props.type === 'email' && !props.pattern) { + extraProps.pattern = '[^@\\s]+@[^@\\s]+\\.[A-Za-z]{2,}' + extraProps.title = props.title ?? 'Введите корректный email с доменной зоной (например, name@example.kz)' + } + return } export function TextArea(props: TextareaHTMLAttributes) {