import React from 'react'; import { Controller, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import Field from './ui/Field'; import Input from './ui/Input'; import MobileInput from './ui/MobileInput'; import SearchableSelect from './ui/SearchableSelect'; import type { SelectOption } from './ui/SearchableSelect'; import PersianDatePicker from './ui/PersianDatePicker'; import { iranNationalCodeOptionalSchema, iranMobileOptionalSchema } from '../lib/utils'; /** * اسکیمای فرم «اطلاعات پرونده». مطابق قواعد بک‌اند: * نام الزامی؛ موبایل در صورت پرشدن باید ^09\d{9}$؛ کدملی در صورت پرشدن ۱۰ رقم. * `birth_date` رشتهٔ میلادی YYYY-MM-DD است؛ تبدیل به timestamp در لایهٔ صفحه انجام می‌شود. */ export const patientFormSchema = z.object({ name: z.string().trim().min(1, 'نام و نام خانوادگی الزامی است'), mobile: iranMobileOptionalSchema, national_code: iranNationalCodeOptionalSchema, gender: z.string().nullable(), birth_date: z.string(), fathers_name: z.string(), marital_status: z.string().nullable(), basic_insurance_id: z.union([z.number(), z.string(), z.null()]), supplementary_insurance_id: z.union([z.number(), z.string(), z.null()]), field_of_study: z.string(), education: z.string().nullable(), job: z.string(), province_id: z.union([z.number(), z.string(), z.null()]), city_id: z.union([z.number(), z.string(), z.null()]), home_phone: z.string(), address: z.string(), postal_code: z.string(), referral_source: z.string().nullable(), description: z.string(), }); export type PatientFormValues = z.infer; export interface PatientFormOptions { gender: SelectOption[]; marital: SelectOption[]; education: SelectOption[]; insurance: SelectOption[]; supplementary: SelectOption[]; province: SelectOption[]; city: SelectOption[]; referral: SelectOption[]; } interface Props { defaultValues: PatientFormValues; recordNumber?: string | null; options: PatientFormOptions; onSubmit: (values: PatientFormValues) => void; isSubmitting?: boolean; /** برای بارگذاری وابستهٔ شهرها هنگام تغییر استان (منطق در صفحه). */ onProvinceChange?: (provinceId: number | null) => void; } const grid: React.CSSProperties = { display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 'var(--gap)', }; export default function PatientRecordInfoForm({ defaultValues, recordNumber, options, onSubmit, isSubmitting, onProvinceChange, }: Props) { const { register, handleSubmit, control, formState: { errors }, } = useForm({ resolver: zodResolver(patientFormSchema), defaultValues, }); const sel = (name: keyof PatientFormValues, label: string, opts: SelectOption[], placeholder = 'انتخاب کنید...') => ( ( )} /> ); return (
{sel('gender', 'جنسیت', options.gender)} ( )} /> ( )} /> {sel('marital_status', 'وضعیت تاهل', options.marital)} {sel('basic_insurance_id', 'بیمه پایه', options.insurance)} {sel('supplementary_insurance_id', 'بیمه تکمیلی', options.supplementary)} {sel('education', 'مقطع تحصیلی', options.education)} ( { field.onChange(v); onProvinceChange?.(v === null ? null : Number(v)); }} placeholder="انتخاب کنید..." /> )} /> {sel('city_id', 'شهر', options.city)} {sel('referral_source', 'نحوه آشنایی', options.referral)}