first commit
This commit is contained in:
327
ui/forms/register-center/RegistrationCenterForm.tsx
Normal file
327
ui/forms/register-center/RegistrationCenterForm.tsx
Normal file
@@ -0,0 +1,327 @@
|
||||
"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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user