167 lines
5.5 KiB
TypeScript
167 lines
5.5 KiB
TypeScript
"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>
|
||
);
|
||
}
|