284 lines
9.3 KiB
TypeScript
284 lines
9.3 KiB
TypeScript
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>
|
||
);
|
||
}
|