328 lines
10 KiB
TypeScript
328 lines
10 KiB
TypeScript
"use client";
|
||
import React, { useState } from "react";
|
||
import {
|
||
Box,
|
||
Button,
|
||
Typography,
|
||
Paper,
|
||
Container,
|
||
useTheme,
|
||
useMediaQuery,
|
||
Chip,
|
||
} from "@mui/material";
|
||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
|
||
import BusinessIcon from "@mui/icons-material/Business";
|
||
import LocationOnIcon from "@mui/icons-material/LocationOn";
|
||
import LocalHospitalIcon from "@mui/icons-material/LocalHospital";
|
||
|
||
const TOTAL_STEPS = 12;
|
||
const STEP_LABELS = [
|
||
"انتخاب مرکز",
|
||
"موقعیت و آدرس",
|
||
"وضعیت فوریت",
|
||
"توضیحات تکمیلی",
|
||
"ساعات کاری",
|
||
"تصاویر مرکز",
|
||
"تجهیزات موجود",
|
||
"پرسنل",
|
||
"بیمههای طرف قرارداد",
|
||
"مجوزها",
|
||
"شرایط پذیرش",
|
||
"بررسی نهایی",
|
||
];
|
||
|
||
type CenterItem = {
|
||
id: string;
|
||
name: string;
|
||
address: string;
|
||
isUrgent: boolean;
|
||
};
|
||
|
||
const centersMock: CenterItem[] = [
|
||
{
|
||
id: "1",
|
||
name: "مرکز درمانی امید",
|
||
address: "تهران، خیابان ولیعصر، بالاتر از پارک ساعی، پلاک ۱۲۳",
|
||
isUrgent: true,
|
||
},
|
||
{
|
||
id: "2",
|
||
name: "کلینیک تخصصی مهر",
|
||
address: "مشهد، بلوار وکیلآباد، بین وکیلآباد ۲۱ و ۲۳",
|
||
isUrgent: false,
|
||
},
|
||
{
|
||
id: "3",
|
||
name: "بیمارستان شبانهروزی آتیه",
|
||
address: "اصفهان، خیابان شریعتی، کوچه ۸، ساختمان آتیه",
|
||
isUrgent: true,
|
||
},
|
||
{
|
||
id: "4",
|
||
name: "مرکز سلامت نوین",
|
||
address: "شیراز، میدان مطهری، خیابان معدل، نبش کوچه ۶",
|
||
isUrgent: false,
|
||
},
|
||
];
|
||
|
||
export default function CenterRegistrationForm() {
|
||
const [activeStep, setActiveStep] = useState(1);
|
||
const [maxStepReached, setMaxStepReached] = useState(1);
|
||
|
||
const [selectedCenterId, setSelectedCenterId] = useState<string | null>(null);
|
||
|
||
const theme = useTheme();
|
||
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
||
|
||
const selectedCenter =
|
||
centersMock.find((center) => center.id === selectedCenterId) || null;
|
||
|
||
const handleNext = () => {
|
||
if (activeStep < TOTAL_STEPS) {
|
||
const nextStep = activeStep + 1;
|
||
setActiveStep(nextStep);
|
||
if (nextStep > maxStepReached) setMaxStepReached(nextStep);
|
||
}
|
||
};
|
||
|
||
const handleBack = () => {
|
||
if (activeStep > 1) setActiveStep((prev) => prev - 1);
|
||
};
|
||
|
||
const goToStep = (step: number) => {
|
||
if (step <= maxStepReached) setActiveStep(step);
|
||
};
|
||
|
||
const renderCenterList = () => {
|
||
return (
|
||
<>
|
||
|
||
<>
|
||
{centersMock.map((center) => {
|
||
const isSelected = selectedCenterId === center.id;
|
||
|
||
return (
|
||
<div className="col-span-1" key={center.id}>
|
||
<Box
|
||
onClick={() => setSelectedCenterId(center.id)}
|
||
sx={{
|
||
p: 2.5,
|
||
borderRadius: "18px",
|
||
border: isSelected
|
||
? "2px solid #2563eb"
|
||
: "1px solid #e2e8f0",
|
||
backgroundColor: isSelected ? "#eff6ff" : "#fff",
|
||
cursor: "pointer",
|
||
transition: "all 0.25s ease",
|
||
boxShadow: isSelected
|
||
? "0 10px 25px -15px rgba(37,99,235,0.45)"
|
||
: "0 4px 12px rgba(15,23,42,0.04)",
|
||
"&:hover": {
|
||
transform: "translateY(-2px)",
|
||
borderColor: "#2563eb",
|
||
boxShadow: "0 12px 24px -16px rgba(37,99,235,0.35)",
|
||
},
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "flex-start",
|
||
justifyContent: "space-between",
|
||
gap: 2,
|
||
flexWrap: "wrap",
|
||
}}
|
||
>
|
||
<Box sx={{ flex: 1, minWidth: 0 }}>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
gap: 1,
|
||
mb: 1,
|
||
}}
|
||
>
|
||
<BusinessIcon sx={{ color: "#2563eb", fontSize: 22 }} />
|
||
<Typography
|
||
sx={{
|
||
fontWeight: 800,
|
||
color: "#0f172a",
|
||
fontSize: "1rem",
|
||
}}
|
||
>
|
||
{center.name}
|
||
</Typography>
|
||
</Box>
|
||
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "flex-start",
|
||
gap: 1,
|
||
}}
|
||
>
|
||
<LocationOnIcon
|
||
sx={{ color: "#94a3b8", fontSize: 18, mt: "2px" }}
|
||
/>
|
||
<Typography
|
||
sx={{
|
||
color: "#64748b",
|
||
fontSize: "0.92rem",
|
||
lineHeight: 1.9,
|
||
}}
|
||
>
|
||
{center.address}
|
||
</Typography>
|
||
</Box>
|
||
</Box>
|
||
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||
<Chip
|
||
icon={<LocalHospitalIcon />}
|
||
label={
|
||
center.isUrgent
|
||
? "استخدام فوری دارد"
|
||
: "استخدام فوری ندارد"
|
||
}
|
||
sx={{
|
||
fontWeight: 700,
|
||
backgroundColor: center.isUrgent
|
||
? "#fee2e2"
|
||
: "#e2e8f0",
|
||
color: center.isUrgent ? "#b91c1c" : "#475569",
|
||
"& .MuiChip-icon": {
|
||
color: center.isUrgent ? "#dc2626" : "#64748b",
|
||
},
|
||
}}
|
||
/>
|
||
|
||
{isSelected && (
|
||
<CheckCircleIcon
|
||
sx={{ color: "#2563eb", fontSize: 24 }}
|
||
/>
|
||
)}
|
||
</Box>
|
||
</Box>
|
||
</Box>
|
||
</div>
|
||
);
|
||
})}
|
||
</>
|
||
</>
|
||
);
|
||
};
|
||
|
||
const renderStepContent = (step: number) => {
|
||
switch (step) {
|
||
case 1:
|
||
return renderCenterList();
|
||
|
||
case 2:
|
||
return selectedCenter ? (
|
||
<Box sx={{ width: "100%" }}>
|
||
<Typography sx={{ fontWeight: 800, color: "#0f172a", mb: 2 }}>
|
||
مرکز انتخابشده
|
||
</Typography>
|
||
|
||
<Box
|
||
sx={{
|
||
p: 3,
|
||
borderRadius: "20px",
|
||
backgroundColor: "#fff",
|
||
border: "1px solid #e2e8f0",
|
||
}}
|
||
>
|
||
<Typography
|
||
sx={{
|
||
fontWeight: 800,
|
||
fontSize: "1.1rem",
|
||
color: "#2563eb",
|
||
mb: 1,
|
||
}}
|
||
>
|
||
{selectedCenter.name}
|
||
</Typography>
|
||
<Typography sx={{ color: "#64748b", mb: 2 }}>
|
||
{selectedCenter.address}
|
||
</Typography>
|
||
<Chip
|
||
label={
|
||
selectedCenter.isUrgent
|
||
? "استخدام فوری دارد"
|
||
: "استخدام فوری ندارد"
|
||
}
|
||
sx={{
|
||
fontWeight: 700,
|
||
backgroundColor: selectedCenter.isUrgent
|
||
? "#dbeafe"
|
||
: "#e2e8f0",
|
||
color: selectedCenter.isUrgent ? "#1d4ed8" : "#475569",
|
||
}}
|
||
/>
|
||
</Box>
|
||
</Box>
|
||
) : (
|
||
<Typography className="text-center text-[#94a3b8]">
|
||
ابتدا از مرحله قبل یک مرکز را انتخاب کنید.
|
||
</Typography>
|
||
);
|
||
|
||
case 3:
|
||
return selectedCenter ? (
|
||
<Box sx={{ textAlign: "center" }}>
|
||
<BusinessIcon
|
||
sx={{
|
||
fontSize: 60,
|
||
color: selectedCenter.isUrgent ? "#ef4444" : "#2563eb",
|
||
mb: 2,
|
||
}}
|
||
/>
|
||
<Typography variant="h6" sx={{ mb: 1, fontWeight: 700 }}>
|
||
وضعیت استخدام فوری
|
||
</Typography>
|
||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||
{selectedCenter.isUrgent
|
||
? "این مرکز دارای استخدام فوری است."
|
||
: "این مرکز در حال حاضر استخدام فوری ندارد."}
|
||
</Typography>
|
||
<Chip
|
||
label={selectedCenter.isUrgent ? "فوری" : "عادی"}
|
||
sx={{
|
||
px: 1,
|
||
fontWeight: 800,
|
||
backgroundColor: selectedCenter.isUrgent
|
||
? "#fee2e2"
|
||
: "#e2e8f0",
|
||
color: selectedCenter.isUrgent ? "#dc2626" : "#475569",
|
||
}}
|
||
/>
|
||
</Box>
|
||
) : (
|
||
<Typography className="text-center text-[#94a3b8]">
|
||
ابتدا یک مرکز انتخاب کنید.
|
||
</Typography>
|
||
);
|
||
|
||
default:
|
||
return (
|
||
<Typography className="text-center text-[#94a3b8]">
|
||
محتوای مرحله <b>«{STEP_LABELS[step - 1]}»</b> <br />
|
||
(در حال توسعه...)
|
||
</Typography>
|
||
);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<div style={{ width: isMobile ? "100%" : "100%", flexGrow: 1 }}>
|
||
<div className="w-full grid grid-cols-2 gap-4">
|
||
{renderStepContent(activeStep)}
|
||
</div>
|
||
</div>
|
||
</>
|
||
);
|
||
}
|