"use client"; import ShiftCard from "@/components/molecules/cards/ShiftCard"; import { DEPARTMENTS } from "@/lib/constants"; import { useShift } from "@/lib/shift-context"; import { useMemo, useState } from "react"; import type { WeeklyScheduleProps } from "./ShiftSchedule.types"; const MONTH_NAMES_EN = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; const DAY_LABELS = ["T2", "T3", "T4", "T5", "T6", "T7", "CN"]; const DAY_LABELS_EN = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; function formatDateShort(d: Date): string { return `${d.getDate().toString().padStart(2, "0")}/${(d.getMonth() + 1).toString().padStart(2, "0")}`; } function formatDateISO(d: Date): string { const y = d.getFullYear(); const m = (d.getMonth() + 1).toString().padStart(2, "0"); const day = d.getDate().toString().padStart(2, "0"); return `${y}-${m}-${day}`; } function isToday(d: Date): boolean { const today = new Date(2026, 3, 10); return ( d.getDate() === today.getDate() && d.getMonth() === today.getMonth() && d.getFullYear() === today.getFullYear() ); } export default function WeeklySchedule({ onShiftClick, onCreateShift, mobileCalendarHeader = false, }: WeeklyScheduleProps) { const { currentDate, getWeekDates, getShiftsForDate, goToNextWeek, goToPrevWeek } = useShift(); const weekDates = getWeekDates(); const [selectedDate, setSelectedDate] = useState(formatDateISO(weekDates[0] ?? currentDate)); const statusDotsByDate = useMemo(() => { const map: Record = {}; weekDates.forEach((date) => { const dateStr = formatDateISO(date); const dayShifts = getShiftsForDate(dateStr); const dots: string[] = []; if (dayShifts.some((s) => s.status === "available")) dots.push("bg-sky-300"); if (dayShifts.some((s) => s.status === "registered")) dots.push("bg-blue-600"); if (dayShifts.some((s) => s.status === "approved_leave")) dots.push("bg-purple-400"); if (dayShifts.some((s) => s.status === "absent")) dots.push("bg-rose-400"); map[dateStr] = dots.slice(0, 3); }); return map; }, [weekDates, getShiftsForDate]); const selectedDateObj = useMemo(() => { const inWeek = weekDates.find((d) => formatDateISO(d) === selectedDate); return inWeek ?? weekDates[0] ?? currentDate; }, [selectedDate, weekDates, currentDate]); const selectedDateStr = formatDateISO(selectedDateObj); const renderMobileDayView = mobileCalendarHeader && (

{MONTH_NAMES_EN[currentDate.getMonth()]} {currentDate.getFullYear()}

{weekDates.map((date, i) => { const dateStr = formatDateISO(date); const active = dateStr === selectedDateStr; const dots = statusDotsByDate[dateStr] ?? []; return ( ); })}
{DEPARTMENTS.map((dept) => { const deptShifts = getShiftsForDate(selectedDateStr).filter((s) => s.department === dept.id); if (deptShifts.length === 0 && !onCreateShift) return null; return (
{dept.name}
{deptShifts.map((shift) => ( ))} {onCreateShift && ( )}
); })}
); if (mobileCalendarHeader) { return renderMobileDayView ?? null; } return (
{weekDates.map((date, i) => ( ))} {DEPARTMENTS.map((dept) => ( {weekDates.map((date, i) => { const dateStr = formatDateISO(date); const shifts = getShiftsForDate(dateStr).filter( (s) => s.department === dept.id, ); return ( ); })} ))}
Bộ phận {DAY_LABELS[i]} {formatDateShort(date)}
{dept.name}
{shifts.map((shift) => ( ))} {onCreateShift && ( )}
); }