Files
hounam-submit-form-frontend/ui/forms/personal/InnerPersonalInfoForm.tsx
2026-06-02 17:08:52 +03:30

327 lines
11 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.
// InnerPersonalInfoForm.tsx
"use client";
import React from "react";
import { Box, Button, MenuItem, TextField } from "@mui/material";
import { Form, type FormikProps } from "formik";
import { MilitaryStatus, PersonalInfoFormValues } from "./types";
import {
EDUCATION_OPTIONS,
HOUSING_OPTIONS,
MILITARY_OPTIONS,
} from "./constants";
import { PersonalInfoFormProps } from "./PersonalInfoForm";
import { handleBack } from "@/core/utils";
type Props = FormikProps<PersonalInfoFormValues> & PersonalInfoFormProps;
export default function InnerPersonalInfoForm(props: Props) {
const { values, errors, touched, setFieldValue, handleChange } = props;
const showSpouseFields = values.maritalStatus === "متاهل";
const showChildrenCount = ["متاهل", "متارکه", "فوت همسر"].includes(
values.maritalStatus,
);
const isPermanentExempt = values.militaryStatus === "معافیت دائم";
const handleMaritalStatusChange = (
e: React.ChangeEvent<HTMLInputElement>,
) => {
const status = e.target.value;
setFieldValue("maritalStatus", status);
// پاکسازی شرطی‌ها
const isMarried = status === "متاهل";
const hasChildren = ["متاهل", "متارکه", "فوت همسر"].includes(status);
if (!isMarried) {
setFieldValue("spouseName", "");
setFieldValue("spouseEducation", "");
setFieldValue("spouseJob", "");
setFieldValue("spouseWorkplace", "");
}
if (!hasChildren) {
setFieldValue("childrenCount", "");
}
};
const handleMilitaryStatusChange = (
e: React.ChangeEvent<HTMLInputElement>,
) => {
const ms = e.target.value as MilitaryStatus;
setFieldValue("militaryStatus", ms);
if (ms !== "معافیت دائم") {
setFieldValue("permanentExemptionReason", "");
}
};
const tf = <K extends keyof PersonalInfoFormValues>(name: K) => ({
name: String(name),
value: values[name] as any,
onChange: handleChange,
fullWidth: true,
error: !!(touched as any)[name] && !!(errors as any)[name],
helperText: (touched as any)[name] ? ((errors as any)[name] as string) : "",
});
return (
<Form>
<Box
sx={{
display: "grid",
gridTemplateColumns: { xs: "1fr", md: "repeat(2, 1fr)" },
gap: 2,
}}
>
{/* وضعیت تاهل */}
<TextField
select
label="وضعیت تاهل"
name="maritalStatus"
value={values.maritalStatus}
onChange={handleMaritalStatusChange}
fullWidth
error={!!touched.maritalStatus && !!errors.maritalStatus}
helperText={
touched.maritalStatus ? (errors.maritalStatus as string) : ""
}
>
<MenuItem value="">انتخاب کنید</MenuItem>
<MenuItem value="مجرد">مجرد</MenuItem>
<MenuItem value="متاهل">متاهل</MenuItem>
<MenuItem value="متارکه">متارکه</MenuItem>
<MenuItem value="فوت همسر">فوت همسر</MenuItem>
</TextField>
{/* همسر (شرطی) */}
{showSpouseFields && (
<>
<TextField label="نام و نام خانوادگی همسر" {...tf("spouseName")} />
<TextField label="تحصیلات همسر" {...tf("spouseEducation")} />
<TextField label="شغل همسر" {...tf("spouseJob")} />
<TextField label="محل کار همسر" {...tf("spouseWorkplace")} />
</>
)}
{/* تعداد فرزند (شرطی) */}
{showChildrenCount && (
<TextField
label="تعداد فرزند"
name="childrenCount"
type="number"
value={values.childrenCount}
onChange={(e) =>
setFieldValue(
"childrenCount",
e.target.value === "" ? "" : Number(e.target.value),
)
}
fullWidth
error={!!touched.childrenCount && !!errors.childrenCount}
helperText={
touched.childrenCount ? (errors.childrenCount as string) : ""
}
/>
)}
{/* وضعیت نظام وظیفه */}
<TextField
select
label="وضعیت نظام وظیفه"
name="militaryStatus"
value={values.militaryStatus}
onChange={handleMilitaryStatusChange}
fullWidth
error={!!touched.militaryStatus && !!errors.militaryStatus}
helperText={
touched.militaryStatus ? (errors.militaryStatus as string) : ""
}
>
<MenuItem value="">انتخاب کنید</MenuItem>
{MILITARY_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
{/* علت معافیت دائم */}
{isPermanentExempt && (
<TextField
label="علت معافیت دائم"
{...tf("permanentExemptionReason")}
/>
)}
{/* تحصیلات پدر/مادر */}
<TextField
select
label="تحصیلات پدر"
name="fatherEducation"
value={values.fatherEducation}
onChange={handleChange}
fullWidth
error={!!touched.fatherEducation && !!errors.fatherEducation}
helperText={
touched.fatherEducation ? (errors.fatherEducation as string) : ""
}
>
<MenuItem value="">انتخاب کنید</MenuItem>
{EDUCATION_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
<TextField label="شغل پدر" {...tf("fatherJob")} />
<TextField
select
label="تحصیلات مادر"
name="motherEducation"
value={values.motherEducation}
onChange={handleChange}
fullWidth
error={!!touched.motherEducation && !!errors.motherEducation}
helperText={
touched.motherEducation ? (errors.motherEducation as string) : ""
}
>
<MenuItem value="">انتخاب کنید</MenuItem>
{EDUCATION_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>
<TextField label="شغل مادر" {...tf("motherJob")} />
{/* وضعیت مسکن / شهر / آدرس */}
<TextField
select
label="وضعیت مسکن"
name="housingStatus"
value={values.housingStatus}
onChange={handleChange}
fullWidth
error={!!touched.housingStatus && !!errors.housingStatus}
helperText={
touched.housingStatus ? (errors.housingStatus as string) : ""
}
>
<MenuItem value="">انتخاب کنید</MenuItem>
{HOUSING_OPTIONS.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</TextField>{" "}
<TextField label="شهر" {...tf("city")} />
<Box sx={{ gridColumn: { md: "span 2" } }}>
<TextField label="آدرس" {...tf("address")} multiline minRows={2} />
</Box>
{/* تلفن‌ها */}
<TextField label="تلفن منزل" {...tf("homePhone")} />
<TextField label="تلفن همراه" {...tf("mobilePhone")} />
<TextField label="تلفن ضروری" {...tf("emergencyPhone")} />
<TextField label="ایمیل" {...tf("email")} />
{/* مدت سکونت */}
<TextField
label="مدت سکونت (سال)"
name="residenceDuration"
type="number"
value={values.residenceDuration}
onChange={(e) =>
setFieldValue(
"residenceDuration",
e.target.value === "" ? "" : Number(e.target.value),
)
}
fullWidth
error={!!touched.residenceDuration && !!errors.residenceDuration}
helperText={
touched.residenceDuration
? (errors.residenceDuration as string)
: ""
}
/>
{/* ایثارگر */}
<TextField
select
label="ایثارگر"
name="isVeteran"
value={String(values.isVeteran)}
onChange={(e) =>
setFieldValue("isVeteran", e.target.value === "true")
}
fullWidth
error={!!touched.isVeteran && !!errors.isVeteran}
helperText={touched.isVeteran ? (errors.isVeteran as string) : ""}
>
<MenuItem value="false">خیر</MenuItem>
<MenuItem value="true">بله</MenuItem>
</TextField>
{/* سوءپیشینه */}
<TextField
select
label="سابقه کیفری"
name="hasCriminalRecord"
value={String(values.hasCriminalRecord)}
onChange={(e) => {
const next = e.target.value === "true";
setFieldValue("hasCriminalRecord", next);
if (!next) setFieldValue("criminalDescription", "");
}}
fullWidth
error={!!touched.hasCriminalRecord && !!errors.hasCriminalRecord}
helperText={
touched.hasCriminalRecord
? (errors.hasCriminalRecord as string)
: ""
}
>
<MenuItem value="false">خیر</MenuItem>
<MenuItem value="true">بله</MenuItem>
</TextField>
{values.hasCriminalRecord && (
<TextField
label="توضیحات سوء پیشینه"
{...tf("criminalDescription")}
/>
)}
</Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
mt: 5,
width: "100%",
}}
>
<Button
disabled={props.step === 1}
type="button"
onClick={() => handleBack(props, "personalInfo")}
sx={{
borderRadius: "12px",
color: "#64748b",
fontWeight: 700,
}}
>
بازگشت
</Button>
<Button
variant="contained"
type="submit"
sx={{
borderRadius: "12px",
px: 4,
py: 1.5,
bgcolor: `${props.step === 12 ? "green" : "#2563eb"}`,
fontWeight: 700,
}}
>
{props.step === 12 ? "اتمام و ثبت نهايي" : "گام بعدی"}
</Button>
</Box>
</Form>
);
}