first commit

This commit is contained in:
2026-05-31 14:22:39 +03:30
commit 98af7d639b
54 changed files with 11545 additions and 0 deletions

View 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>
</>
);
}