first commit

This commit is contained in:
2026-05-31 14:22:39 +03:30
commit 98af7d639b
54 changed files with 11545 additions and 0 deletions

View File

@@ -0,0 +1,283 @@
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>
);
}