diff --git a/src/food-market.public/src/components/SignupForm.tsx b/src/food-market.public/src/components/SignupForm.tsx
index baa5a9b..64874d6 100644
--- a/src/food-market.public/src/components/SignupForm.tsx
+++ b/src/food-market.public/src/components/SignupForm.tsx
@@ -2,8 +2,6 @@ import { useState } from 'react'
import { validateEmail, validatePassword, validatePhone } from '@/lib/validation'
import { PhoneInput } from '@/components/PhoneInput'
-// Админский / API endpoint — переключается через PUBLIC_APP_URL на этапе
-// билда. Дефолт — admin.food-market.kz (там и API и админ-SPA).
const APP_URL = (import.meta.env.PUBLIC_APP_URL as string | undefined) ?? 'https://admin.food-market.kz'
const API_URL = APP_URL
@@ -81,30 +79,77 @@ export default function SignupForm({ defaultPlan = 'start' }: Props) {
{error && (
{error}
)}
+
- { setEmail(e.target.value); setFieldErrors(p => ({...p, email: undefined})) }}
- onBlur={() => { const e = validateEmail(email); setFieldErrors(p => ({...p, email: e ?? undefined})) }}
- autoComplete="email" placeholder="name@example.kz" className={inputCls(!!fieldErrors.email)} />
+ {
+ const v = e.target.value
+ setEmail(v)
+ // Ре-валидируем только если ошибка уже показана (не мешаем первичному вводу)
+ setFieldErrors(p => p.email ? {...p, email: validateEmail(v) ?? undefined} : p)
+ }}
+ onBlur={(e) => {
+ // e.target.value — реальное DOM-значение, без stale closure
+ setFieldErrors(p => ({...p, email: validateEmail(e.target.value) ?? undefined}))
+ }}
+ autoComplete="email"
+ placeholder="name@example.kz"
+ className={inputCls(!!fieldErrors.email)}
+ />
+
- { setPassword(e.target.value); setFieldErrors(p => ({...p, password: undefined})) }}
- onBlur={() => { const e = validatePassword(password); setFieldErrors(p => ({...p, password: e ?? undefined})) }}
- autoComplete="new-password" className={inputCls(!!fieldErrors.password)} />
+ {
+ const v = e.target.value
+ setPassword(v)
+ setFieldErrors(p => p.password ? {...p, password: validatePassword(v) ?? undefined} : p)
+ }}
+ onBlur={(e) => {
+ setFieldErrors(p => ({...p, password: validatePassword(e.target.value) ?? undefined}))
+ }}
+ autoComplete="new-password"
+ className={inputCls(!!fieldErrors.password)}
+ />
+
- { setOrgName(e.target.value); setFieldErrors(p => ({...p, orgName: undefined})) }}
- onBlur={() => { setFieldErrors(p => ({...p, orgName: !orgName.trim() ? 'Название магазина обязательно для заполнения' : undefined})) }}
- placeholder="Наименование организации" className={inputCls(!!fieldErrors.orgName)} />
+ {
+ const v = e.target.value
+ setOrgName(v)
+ setFieldErrors(p => p.orgName ? {...p, orgName: !v.trim() ? 'Название магазина обязательно для заполнения' : undefined} : p)
+ }}
+ onBlur={(e) => {
+ setFieldErrors(p => ({...p, orgName: !e.target.value.trim() ? 'Название магазина обязательно для заполнения' : undefined}))
+ }}
+ placeholder="Наименование организации"
+ className={inputCls(!!fieldErrors.orgName)}
+ />
+
- { setPhone(v); setFieldErrors(p => ({...p, phone: undefined})) }}
- onBlur={() => { const e = validatePhone(phone); setFieldErrors(p => ({...p, phone: e ?? undefined})) }}
- required className={inputCls(!!fieldErrors.phone)} />
+ {
+ setPhone(v)
+ setFieldErrors(p => p.phone ? {...p, phone: validatePhone(v) ?? undefined} : p)
+ }}
+ onBlur={(e) => {
+ // e.target.value — display-формат "+7 7XX XXX XX XX", validatePhone его принимает
+ setFieldErrors(p => ({...p, phone: validatePhone((e as React.FocusEvent).target.value) ?? undefined}))
+ }}
+ required
+ className={inputCls(!!fieldErrors.phone)}
+ />
+
Тариф
@@ -121,6 +166,7 @@ export default function SignupForm({ defaultPlan = 'start' }: Props) {
))}
+
{fieldErrors.agree &&
{fieldErrors.agree}
}
+