export function adaptSlots(slotsResponse) { const sessions = slotsResponse?.data?.sessions ?? slotsResponse?.sessions ?? []; // Group slots by the shifts the backend already returns; the front does not // decide shift boundaries (no hard-coded morning/evening split). Each session // becomes one tab labelled with its own time range. return sessions .filter((session) => Array.isArray(session.slots) && session.slots.length > 0) .map((session) => ({ start_time: session.start_time, end_time: session.end_time, label: `${session.start_time} - ${session.end_time}`, slots: session.slots, })); } /** * حالت سرویسی: پاسخ `appointment-service-slots` فقط `start_times` مسطح می‌دهد و مرزِ * شیفت‌ها را نمی‌گوید. یک session ساخته می‌شود تا مثل حالت اسلاتی رندر شود. * * ⚠️ **چرا شیفت‌ها تفکیک نمی‌شوند:** با فهرست مسطح، شکافِ بین دو شیفت از شکافِ یک نوبتِ * اشغال‌شده قابل تفکیک نیست. گام عادی `مدت + بافر` است، و دو نوبت پشت‌سرهم شکافی * می‌سازد که از تعطیلیِ میانِ صبح و عصر تشخیص‌پذیر نیست. هر آستانه‌ای که این دو را * جدا کند، روی سرویس‌های بلند (گام > آستانه) هر اسلات را یک تب می‌کند و روی نوبت‌های * اشغال، تبِ جعلی می‌سازد — یعنی اطلاعات غلط، که از یک تبِ درست بدتر است. * * راه درست، گروه‌بندی از سمت سرور است (endpoint چندمنبعی، تسک ۰۶). تا آن زمان یک * session با **بازهٔ واقعی** برگردانده می‌شود. */ export function adaptServiceSlots(slotsResponse) { const payload = slotsResponse?.data ?? slotsResponse ?? {}; const starts = payload.start_times ?? []; if (!starts.length) return []; const first = starts[0]; const last = starts[starts.length - 1]; // پایانِ آخرین نوبت، نه زمانِ **شروعِ** آن — قبلاً `start_time` گذاشته می‌شد و برچسب // بازه را کوتاه‌تر از واقعیت نشان می‌داد. const endTime = last.end_time ?? addMinutes(last.start_time, payload.total_duration_minutes); return [ { start_time: first.start_time, end_time: endTime, label: `${first.start_time} - ${endTime}`, slots: starts.map((s) => ({ ...s, is_available: true })), }, ]; } /** `"09:00" + 35` → `"09:35"`. فقط fallback؛ پاسخ سرور `end_time` دارد. */ function addMinutes(time, minutes) { const [h, m] = String(time).split(":").map(Number); if (!Number.isFinite(h) || !Number.isFinite(m) || !Number.isFinite(minutes)) return time; const total = h * 60 + m + minutes; const hh = String(Math.floor(total / 60) % 24).padStart(2, "0"); const mm = String(total % 60).padStart(2, "0"); return `${hh}:${mm}`; } export function hasAvailable(slots) { return Array.isArray(slots) && slots.some((slot) => slot.is_available); }