update validation

This commit is contained in:
smanylov
2026-01-10 15:12:51 +07:00
parent b5754b75a8
commit 31af7036a3
7 changed files with 316 additions and 96 deletions
+51 -73
View File
@@ -1,4 +1,6 @@
import * as z from 'zod'
import { createValidationSchema } from "@/app/lib/validation-config-parser";
import validationConfig from '@/app/lib/validation-config.json';
export type FormState =
| {
@@ -16,80 +18,56 @@ export type FormAction = (
formData: FormData
) => Promise<FormState>
const emailRegex = /^([a-z0-9.\-_]+|[а-яё0-9.\-_]+)@(([a-z0-9.\-]+)\.([a-z]{2,})|([a-z0-9.\-]+)\.([а-яё]{2,})|([а-яё0-9.\-]+)\.([a-z]{2,})|([а-яё0-9.\-]+)\.([а-яё]{2,}))$/i;
interface FieldConfig {
maxSize?: { value: number; message: string };
minSize?: { value: number; message: string };
allowedSymbols?: { value: string; message: string };
optional?: { value: boolean };
requiredDigit?: { value: boolean; message: string };
requiredLetter?: { value: boolean; message: string };
caseType?: { value: 'LOWER' | 'UPPER' | 'ANY'; message: string };
emailValidation?: { value: boolean; message: string };
}
interface ValidationConfig {
[key: string]: FieldConfig;
}
const defaultConfig = validationConfig as ValidationConfig;
let cachedSignupSchema: any = null;
let schemaPromise: Promise<any> | null = null;
async function loadConfigFromBackend(): Promise<any> {
try {
const response = await fetch('/api/validation-config');
if (!response.ok) throw new Error('Failed to load config');
return await response.json();
} catch (error) {
console.error('Using default validation config:', error);
return defaultConfig;
}
}
export async function getSignupFormSchema() {
console.log('get scheme');
if (cachedSignupSchema) {
return cachedSignupSchema;
}
if (!schemaPromise) {
schemaPromise = (async () => {
const config = await loadConfigFromBackend();
cachedSignupSchema = createValidationSchema(config);
return cachedSignupSchema;
})();
}
return await schemaPromise;
}
export const SignupFormSchema = createValidationSchema(defaultConfig);
export const SignupFormSchema = z
.object({
fullName: z
.string()
.min(2, { error: 'register-error-min-name' })
.max(100, { error: 'register-error-max-name' })
.regex(/^[a-zA-Zа-яА-ЯёЁ\s\-'.]*$/, { message: 'register-error-name-not-allowed-symbols' })
.trim(),
email: z
.string()
.trim()
.max(254, { error: 'register-error-max-email' })
.refine(
(value) => value === value.toLowerCase(),
{ message: 'register-error-email-no-uppercase' }
)
.refine(
(value) => emailRegex.test(value),
{ message: 'register-error-email-invalid' }
),
phone: z
.string()
.min(12, { error: 'register-error-phone-min' }),
password: z
.string()
.min(8, { error: 'register-error-password-symbols' })
.regex(/[a-zA-Zа-яёА-ЯЁ]/, { error: 'register-error-password-one-letter' })
.regex(/[0-9]/, { error: 'register-error-password-one-digit' })
.max(124, { error: 'register-error-max-passowrd' })
.trim(),
confirm_password: z
.string(),
agree: z
.string()
.min(2, { error: 'register-error-agree' }),
companyName: z
.string()
.optional()
.nullable()
.refine(
(value) => {
if (!value || value.trim().length === 0) return true;
return value.trim().length >= 2;
},
{ message: 'register-error-company-name-min' }
)
.refine(
(value) => {
const trimmed = value ? value.trim() : '';
return trimmed.length === 0 || trimmed.length <= 200;
},
{
message: 'register-error-company-name-max',
path: ['companyName']
}
)
.refine(
(value) => {
if (!value || value.trim().length === 0) return true;
const regex = /^[a-zA-Zа-яА-ЯёЁ0-9\s\-&.,'"()]+$/;
return regex.test(value);
},
{
message: 'companyName-invalid-chars',
path: ['companyName']
}
),
})
.refine((data) => data.password === data.confirm_password, {
message: 'repeat-password',
path: ['confirm_password'],
});
export const loginFormSchema = z
.object({