Files
goodgo-platform/apps/web/lib/validations/auth.ts
Ho Ngoc Hai fbe28102a1 fix(web): include ward in address display across card views
- property-card.tsx: add ward between address and district in both
  card (line 189) and list (line 95) layouts
- transfer-listing-card.tsx: conditionally prepend ward to
  district/city when ward is non-null
- property-card.spec.tsx: update address test to assert ward is shown,
  add list-layout ward regression test (21/21 pass)

Standard format: {address}, {ward}, {district}, {city}
Compact (project-card, industrial-listing-card): district/city only —
intentional; ProjectSummary has no ward field.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 11:57:09 +07:00

40 lines
1.2 KiB
TypeScript

import { z } from 'zod';
import { VN_PHONE_REGEX as phoneRegex } from '@/lib/phone';
export const loginSchema = z.object({
phone: z
.string()
.min(1, 'Vui lòng nhập số điện thoại')
.regex(phoneRegex, 'Số điện thoại không hợp lệ'),
password: z.string().min(1, 'Vui lòng nhập mật khẩu'),
});
export const registerSchema = z
.object({
fullName: z
.string()
.min(1, 'Vui lòng nhập họ tên')
.min(2, 'Họ tên phải có ít nhất 2 ký tự'),
phone: z
.string()
.min(1, 'Vui lòng nhập số điện thoại')
.regex(phoneRegex, 'Số điện thoại không hợp lệ'),
email: z
.string()
.email('Email không hợp lệ')
.optional()
.or(z.literal('')),
password: z
.string()
.min(8, 'Mật khẩu phải có ít nhất 8 ký tự'),
confirmPassword: z.string().min(1, 'Vui lòng xác nhận mật khẩu'),
})
.refine((data) => data.password === data.confirmPassword, {
message: 'Mật khẩu xác nhận không khớp',
path: ['confirmPassword'],
});
export type LoginFormData = z.infer<typeof loginSchema>;
export type RegisterFormData = z.infer<typeof registerSchema>;