"use client"; import { useEffect, useState } from "react"; import { Box, Button, Modal } from "@mui/material"; import moment from "moment-jalaali"; import { styleDefault } from "@/mui"; import CloseModalD from "@/components/icons/CloseModalD"; import { request } from "@/services/response"; import { adaptServiceSlots } from "@/lib/appointmentSlots"; const DAYS_AHEAD = 14; /** چهارده روز آینده — نوبتی که بیمار خودش جابه‌جا می‌کند، ماه‌ها جلوتر نمی‌رود. */ function nextDays() { return Array.from({ length: DAYS_AHEAD }, (_, i) => { const day = moment().add(i, "day"); return { value: day.format("YYYY-MM-DD"), label: day.format("jD jMMMM"), weekday: day.format("dddd"), }; }); } /** * جابه‌جایی نوبت از پنل کاربر. * * مدت را **سرور** حساب می‌کند: بیمار فقط زمان شروع می‌فرستد. اگر فرانت مدت را می‌فرستاد، * دو محاسبهٔ موازی داشتیم و روزی که تعرفه یا مدت سرویس عوض می‌شد، نوبت با مدت کهنه * جابه‌جا می‌شد. * * وقت‌ها با `exclude_appointment_uuid` گرفته می‌شوند تا خودِ نوبت فعلی جای خالی حساب * شود؛ وگرنه بیمار ساعت خودش را «پر» می‌بیند. */ function RescheduleModal({ appointment, loading, onDone }) { const [open, setOpen] = useState(false); const [date, setDate] = useState(null); const [slots, setSlots] = useState([]); const [picked, setPicked] = useState(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const days = nextDays(); const doctorUuid = appointment?.doctor?.uuid; useEffect(() => { if (!open || !date || !doctorUuid || !appointment?.uuid) return; let cancelled = false; setError(null); setPicked(null); setBusy(true); request .getServiceSlotsForReschedule( doctorUuid, date, appointment.uuid, (appointment.service_items ?? []).map((s) => s.uuid).filter(Boolean) ) .then((res) => { if (cancelled) return; const groups = adaptServiceSlots(res); setSlots(groups.flatMap((g) => g.slots ?? [])); }) .catch((e) => { if (!cancelled) setError(e?.message || "گرفتن وقت‌های آزاد ناموفق بود"); }) .finally(() => { if (!cancelled) setBusy(false); }); return () => { cancelled = true; }; }, [open, date, doctorUuid, appointment?.uuid]); const close = () => { setOpen(false); setDate(null); setSlots([]); setPicked(null); setError(null); }; const submit = async () => { if (!picked) return; setBusy(true); setError(null); try { await request.serviceReschedule(appointment.uuid, { start: picked.start }); close(); onDone?.(); } catch (e) { // ۴۰۹ یعنی همین لحظه کس دیگری همان وقت را گرفت — پیام سرور دقیقاً همین را می‌گوید // و فهرست دوباره خوانده می‌شود تا بیمار جایگزین ببیند. setError(e?.message || "جابه‌جایی نوبت ناموفق بود"); setDate((d) => d); setBusy(false); } }; return (

جابه‌جایی نوبت

روز و ساعت تازه را انتخاب کنید. سرویس‌های نوبت و مدت آن تغییری نمی‌کنند.

{days.map((day) => ( ))}
{busy && (

در حال بررسی وقت‌های آزاد…

)} {!busy && date && slots.length === 0 && !error && (

در این روز وقت آزادی نیست؛ روز دیگری را امتحان کنید.

)} {slots.length > 0 && (
{slots.map((slot) => ( ))}
)} {error &&

{error}

}
); } export default RescheduleModal;