admin/validation/withdrawal.ts
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

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>