Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
import { texts } from '@/texts'
|
|
|
|
const v = texts.validation.withdrawal
|
|
const nationalId = texts.validation.nationalId
|
|
|
|
export const CreateBankAccountFormValidation = z
|
|
.object({
|
|
ownerType: z.enum(['guest', 'organizer']),
|
|
accountHolder: z.string().trim().min(3, v.accountHolderRequired).max(200, v.accountHolderMax),
|
|
iban: z
|
|
.string()
|
|
.trim()
|
|
.transform((value) => value.toUpperCase().replace(/\s+/g, ''))
|
|
.refine((value) => /^IR\d{24}$/.test(value), v.ibanInvalid),
|
|
nationalCode: z.string().trim().optional().or(z.literal('')),
|
|
bankName: z.string().trim().max(100, v.bankNameMax).optional().or(z.literal('')),
|
|
})
|
|
.superRefine((value, ctx) => {
|
|
if (value.ownerType !== 'guest') return
|
|
|
|
const nationalCode = value.nationalCode ?? ''
|
|
|
|
if (!nationalCode) {
|
|
ctx.addIssue({ code: 'custom', path: ['nationalCode'], message: nationalId.nationalCodeRequired })
|
|
|
|
return
|
|
}
|
|
if (!/^\d{10}$/.test(nationalCode)) {
|
|
ctx.addIssue({ code: 'custom', path: ['nationalCode'], message: nationalId.nationalCodeDigits })
|
|
}
|
|
})
|
|
|
|
export type CreateBankAccountFormValues = z.infer<typeof CreateBankAccountFormValidation>
|
|
|
|
export const CreateWithdrawalRequestFormValidation = z.object({
|
|
bankAccountId: z.string().min(1, v.bankAccountRequired),
|
|
amount: z
|
|
.string()
|
|
.trim()
|
|
.min(1, v.amountRequired)
|
|
.refine((value) => /^\d+$/.test(value), v.amountInteger)
|
|
.refine((value) => Number(value) > 0, v.amountPositive),
|
|
})
|
|
|
|
export type CreateWithdrawalRequestFormValues = z.infer<typeof CreateWithdrawalRequestFormValidation>
|