change some files

This commit is contained in:
2026-06-02 17:08:52 +03:30
parent b8dc1d0e1b
commit cfb48c5bb0
76 changed files with 5204 additions and 2555 deletions

View File

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