This commit is contained in:
2026-05-31 18:00:43 +03:30
parent 98af7d639b
commit b241d12ff5
20 changed files with 939 additions and 797 deletions

View File

@@ -0,0 +1,166 @@
"use client";
import {
Box,
Typography,
useTheme,
useMediaQuery,
Chip,
Button,
FormHelperText,
} from "@mui/material";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import { Form, FormikProps } from "formik";
import BusinessIcon from "@mui/icons-material/Business";
import LocationOnIcon from "@mui/icons-material/LocationOn";
import LocalHospitalIcon from "@mui/icons-material/LocalHospital";
import { useGetAllCenters } from "@/hooks/center.hook";
import {
RegistrationCenterFormProps,
RegistrationCenterFormValues,
} from "./RegistrationCenterForm";
import { CenterItem } from "@/core/types";
// تعریف اینترفیس برای تمیزی بیشتر
interface InnerFormProps
extends
FormikProps<RegistrationCenterFormValues>,
RegistrationCenterFormProps {}
export default function InnerRegistrationCenterForm(props: InnerFormProps) {
const { data } = useGetAllCenters();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
const handleBack = () => {
props.update({ registrationCenter: props.values.selectedCenter});
props.setStep((prev) => Math.max(1, prev - 1));
};
// منطق نمایش خطا
const isSelectedCenterError =
(props.touched.selectedCenter || props.submitCount > 0) &&
!!props.errors.selectedCenter;
const handleCenterSelect = (center: CenterItem) => {
props.setFieldValue("selectedCenter", center);
props.setFieldTouched("selectedCenter", true, true); // فعال کردن حالت لمس شده
};
const handleNext = async () => {
// اگر مرحله اول است، فیلد را لمس کن تا اگر خالی بود خطا نشان دهد
if (props.step === 1) {
props.setFieldTouched("selectedCenter", true, true);
}
// اعتبارسنجی دستی کل فرم
const errors = await props.validateForm();
// اگر در گام فعلی خطایی وجود ندارد، برو مرحله بعد
if (Object.keys(errors).length === 0) {
if (props.step === 12) {
props.submitForm(); // ثبت نهایی
} else {
props.setStep(props.step + 1);
}
}
};
const renderCenterList = () => (
<Box sx={{ width: "100%", gridColumn: "1 / -1" }}>
<div className="w-full grid grid-cols-2 gap-4">
{data?.data.map((center: CenterItem) => {
const isSelected = props.values.selectedCenter?.id === center.id;
return (
<div className="col-span-1" key={center.id}>
<Box
onClick={() => handleCenterSelect(center)}
sx={{
p: 2.5,
borderRadius: "18px",
border: isSelected
? "2px solid #2563eb"
: isSelectedCenterError
? "2px solid #d32f2f"
: "1px solid #e2e8f0",
backgroundColor: isSelected ? "#eff6ff" : "#fff",
cursor: "pointer",
transition: "all 0.25s ease",
"&:hover": { borderColor: "#2563eb" },
}}
>
<Box sx={{ display: "flex", alignItems: "flex-start", gap: 2 }}>
<Box sx={{ flex: 1 }}>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
mb: 1,
}}
>
<BusinessIcon sx={{ color: "#2563eb", fontSize: 22 }} />
<Typography sx={{ fontWeight: 800, color: "#0f172a" }}>
{center.name}
</Typography>
</Box>
<Typography sx={{ color: "#64748b", fontSize: "0.92rem" }}>
{center.address}
</Typography>
</Box>
{isSelected && <CheckCircleIcon sx={{ color: "#2563eb" }} />}
</Box>
</Box>
</div>
);
})}
</div>
{/* نمایش پیام خطا به صورت تمیز زیر لیست */}
{isSelectedCenterError && (
<FormHelperText
error
sx={{ mt: 2, fontSize: "0.9rem", fontWeight: 600 }}
>
{props.errors.selectedCenter as string}
</FormHelperText>
)}
</Box>
);
return (
<Form>
<div style={{ width: "100%", flexGrow: 1 }}>
{/* رندر محتوای استپ ها */}
{props.step === 1 ? (
renderCenterList()
) : (
<Typography>محتوای مرحله {props.step}</Typography>
)}
</div>
<Box sx={{ display: "flex", justifyContent: "space-between", mt: 5 }}>
<Button
disabled={props.step === 1}
type="button"
onClick={handleBack}
sx={{ borderRadius: "12px", color: "#64748b", fontWeight: 700 }}
>
بازگشت
</Button>
<Button
variant="contained"
type="button" // به جای submit از button استفاده کردیم تا با تابع خودمان چک شود
onClick={handleNext}
sx={{
borderRadius: "12px",
px: 4,
py: 1.5,
bgcolor: props.step === 12 ? "green" : "#2563eb",
fontWeight: 700,
}}
>
{props.step === 12 ? "اتمام و ثبت نهايي" : "گام بعدی"}
</Button>
</Box>
</Form>
);
}