Files
hounam-submit-form-frontend/ui/forms/PersonalInfoForm.tsx
2026-05-31 14:22:39 +03:30

284 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useEffect, useState } from "react";
import { Box, MenuItem, TextField } from "@mui/material";
type MilitaryStatus =
| ""
| "کارت پایان خدمت"
| "در حال خدمت"
| "معافیت تحصیلی"
| "معافیت دائم"
| "انجام نشده";
type EducationLevel =
| ""
| "زیر دیپلم"
| "دیپلم"
| "دانشجو"
| "کاردانی"
| "کارشناسی"
| "کارشناسی ارشد"
| "دکترا";
export interface PersonalInfoFormState {
applicantId: string;
maritalStatus: string;
// نظام وظیفه
militaryStatus: MilitaryStatus;
permanentExemptionReason: string; // علت معافیت دائم (شرطی)
// والدین
fatherEducation: EducationLevel;
fatherJob: string;
motherEducation: EducationLevel;
motherJob: string;
housingStatus: string;
city: string;
address: string;
homePhone: string;
mobilePhone: string;
emergencyPhone: string;
email: string;
residenceDuration: number | "";
isVeteran: boolean;
hasCriminalRecord: boolean;
criminalDescription: string;
// فیلدهای همسر/فرزند
spouseName?: string;
spouseEducation?: string;
spouseJob?: string;
spouseWorkplace?: string;
childrenCount?: number | "";
}
const initialValues: PersonalInfoFormState = {
applicantId: "",
maritalStatus: "",
militaryStatus: "",
permanentExemptionReason: "",
fatherEducation: "",
fatherJob: "",
motherEducation: "",
motherJob: "",
housingStatus: "",
city: "",
address: "",
homePhone: "",
mobilePhone: "",
emergencyPhone: "",
email: "",
residenceDuration: "",
isVeteran: false,
hasCriminalRecord: false,
criminalDescription: "",
spouseName: "",
spouseEducation: "",
spouseJob: "",
spouseWorkplace: "",
childrenCount: "",
};
const MILITARY_OPTIONS: Exclude<MilitaryStatus, "">[] = [
"کارت پایان خدمت",
"در حال خدمت",
"معافیت تحصیلی",
"معافیت دائم",
"انجام نشده",
];
const EDUCATION_OPTIONS: Exclude<EducationLevel, "">[] = [
"زیر دیپلم",
"دیپلم",
"دانشجو",
"کاردانی",
"کارشناسی",
"کارشناسی ارشد",
"دکترا",
];
export default function PersonalInfoForm({
value,
onChange,
}: {
value?: PersonalInfoFormState;
onChange?: (val: PersonalInfoFormState) => void;
}) {
const [formData, setFormData] = useState<PersonalInfoFormState>(value || initialValues);
// اگر prop value از بیرون تغییر کرد، state داخلی sync شود
useEffect(() => {
if (value) setFormData(value);
}, [value]);
const setNext = (updater: (prev: PersonalInfoFormState) => PersonalInfoFormState) => {
setFormData((prev) => {
const next = updater(prev);
onChange?.(next);
return next;
});
};
const handleChange =
<K extends keyof PersonalInfoFormState>(field: K) =>
(e: React.ChangeEvent<HTMLInputElement>) => {
const val = e.target.value as PersonalInfoFormState[K];
setNext((p) => ({ ...p, [field]: val }));
};
const handleNumber =
<K extends keyof PersonalInfoFormState>(field: K) =>
(e: React.ChangeEvent<HTMLInputElement>) => {
const v = e.target.value;
setNext((p) => ({ ...p, [field]: (v === "" ? "" : Number(v)) as PersonalInfoFormState[K] }));
};
// تغییر وضعیت تاهل + پاکسازی فیلدهای شرطی مربوط به همسر/فرزند
const handleMaritalStatusChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const status = e.target.value;
setNext((p) => {
const isMarried = status === "متاهل";
const hasChildren = ["متاهل", "متارکه", "فوت همسر"].includes(status);
return {
...p,
maritalStatus: status,
spouseName: isMarried ? p.spouseName : "",
spouseEducation: isMarried ? p.spouseEducation : "",
spouseJob: isMarried ? p.spouseJob : "",
spouseWorkplace: isMarried ? p.spouseWorkplace : "",
childrenCount: hasChildren ? p.childrenCount : "",
};
});
};
// تغییر وضعیت نظام وظیفه + پاکسازی علت معافیت در صورت عدم نیاز
const handleMilitaryStatusChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const ms = e.target.value as MilitaryStatus;
setNext((p) => ({
...p,
militaryStatus: ms,
permanentExemptionReason: ms === "معافیت دائم" ? p.permanentExemptionReason : "",
}));
};
const isPermanentExempt = formData.militaryStatus === "معافیت دائم";
return (
<Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "repeat(2, 1fr)" }, gap: 2 }}>
{/* وضعیت تاهل */}
<TextField select label="وضعیت تاهل" value={formData.maritalStatus} onChange={handleMaritalStatusChange} fullWidth>
<MenuItem value="">انتخاب کنید</MenuItem>
<MenuItem value="مجرد">مجرد</MenuItem>
<MenuItem value="متاهل">متاهل</MenuItem>
<MenuItem value="متارکه">متارکه</MenuItem>
<MenuItem value="فوت همسر">فوت همسر</MenuItem>
</TextField>
{/* همسر (شرطی) */}
{formData.maritalStatus === "متاهل" && (
<>
<TextField label="نام و نام خانوادگی همسر" value={formData.spouseName} onChange={handleChange("spouseName")} fullWidth />
<TextField label="تحصیلات همسر" value={formData.spouseEducation} onChange={handleChange("spouseEducation")} fullWidth />
<TextField label="شغل همسر" value={formData.spouseJob} onChange={handleChange("spouseJob")} fullWidth />
<TextField label="محل کار همسر" value={formData.spouseWorkplace} onChange={handleChange("spouseWorkplace")} fullWidth />
</>
)}
{/* تعداد فرزند (شرطی) */}
{["متاهل", "متارکه", "فوت همسر"].includes(formData.maritalStatus) && (
<TextField
label="تعداد فرزند"
type="number"
value={formData.childrenCount}
onChange={handleNumber("childrenCount")}
fullWidth
/>
)}
{/* وضعیت نظام وظیفه (لیستی) */}
<TextField select label="وضعیت نظام وظیفه" value={formData.militaryStatus} onChange={handleMilitaryStatusChange} fullWidth>
<MenuItem value="">انتخاب کنید</MenuItem>
{MILITARY_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
{/* علت معافیت دائم (شرطی) */}
{isPermanentExempt && (
<TextField
label="علت معافیت دائم"
value={formData.permanentExemptionReason}
onChange={handleChange("permanentExemptionReason")}
fullWidth
/>
)}
{/* تحصیلات پدر/مادر (لیستی) */}
<TextField select label="تحصیلات پدر" value={formData.fatherEducation} onChange={handleChange("fatherEducation")} fullWidth>
<MenuItem value="">انتخاب کنید</MenuItem>
{EDUCATION_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
<TextField label="شغل پدر" value={formData.fatherJob} onChange={handleChange("fatherJob")} fullWidth />
<TextField select label="تحصیلات مادر" value={formData.motherEducation} onChange={handleChange("motherEducation")} fullWidth>
<MenuItem value="">انتخاب کنید</MenuItem>
{EDUCATION_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
<TextField label="شغل مادر" value={formData.motherJob} onChange={handleChange("motherJob")} fullWidth />
{/* بقیه فیلدهای قبلی (نمونه، اگر لازم داری کاملش می‌کنم یا در همین فایل نگه می‌داریم) */}
<TextField label="شهر" value={formData.city} onChange={handleChange("city")} fullWidth />
<TextField label="تلفن منزل" value={formData.homePhone} onChange={handleChange("homePhone")} fullWidth />
<TextField label="تلفن همراه" value={formData.mobilePhone} onChange={handleChange("mobilePhone")} fullWidth />
<TextField label="ایمیل" value={formData.email} onChange={handleChange("email")} fullWidth />
<Box sx={{ gridColumn: { md: "span 2" } }}>
<TextField label="آدرس" value={formData.address} onChange={handleChange("address")} fullWidth multiline minRows={2} />
</Box>
<TextField
select
label="سابقه کیفری"
value={String(formData.hasCriminalRecord)}
onChange={(e) => setNext((p) => ({ ...p, hasCriminalRecord: e.target.value === "true", criminalDescription: e.target.value === "true" ? p.criminalDescription : "" }))}
fullWidth
>
<MenuItem value="false">خیر</MenuItem>
<MenuItem value="true">بله</MenuItem>
</TextField>
{formData.hasCriminalRecord && (
<TextField
label="توضیحات سوء پیشینه"
value={formData.criminalDescription}
onChange={handleChange("criminalDescription")}
fullWidth
/>
)}
</Box>
);
}