"use client"; import { useRouter } from "next/navigation"; import { useState, useTransition } from "react"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; import { Weekday } from "@/generated/prisma/enums"; import { saveWorkingHoursAction } from "../actions/working-hours"; const DAY_ORDER: Weekday[] = [ Weekday.MONDAY, Weekday.TUESDAY, Weekday.WEDNESDAY, Weekday.THURSDAY, Weekday.FRIDAY, Weekday.SATURDAY, Weekday.SUNDAY, ]; const DAY_LABEL: Record = { MONDAY: "Monday", TUESDAY: "Tuesday", WEDNESDAY: "Wednesday", THURSDAY: "Thursday", FRIDAY: "Friday", SATURDAY: "Saturday", SUNDAY: "Sunday", }; interface DayState { dayOfWeek: Weekday; isOff: boolean; startTime: string; // "HH:MM" endTime: string; } function toTimeString(minutes: number | null): string { if (minutes === null) return "09:00"; const h = Math.floor(minutes / 60); const m = minutes % 60; return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`; } function toMinutes(time: string): number { const [h, m] = time.split(":").map(Number); return (h ?? 0) * 60 + (m ?? 0); } export interface InitialWorkingHoursRow { dayOfWeek: Weekday; isOff: boolean; startMinutes: number | null; endMinutes: number | null; } export function WorkingHoursForm({ initialRows, businessHoursLabel }: { initialRows: InitialWorkingHoursRow[]; businessHoursLabel: Record }) { const router = useRouter(); const [days, setDays] = useState(() => DAY_ORDER.map((dayOfWeek) => { const existing = initialRows.find((r) => r.dayOfWeek === dayOfWeek); return { dayOfWeek, isOff: existing?.isOff ?? true, startTime: toTimeString(existing?.startMinutes ?? null), endTime: toTimeString(existing?.endMinutes ?? 19 * 60), }; }), ); const [error, setError] = useState(null); const [saved, setSaved] = useState(false); const [isPending, startTransition] = useTransition(); const updateDay = (dayOfWeek: Weekday, patch: Partial) => { setSaved(false); setDays((prev) => prev.map((d) => (d.dayOfWeek === dayOfWeek ? { ...d, ...patch } : d))); }; const copyMondayToAll = () => { const monday = days.find((d) => d.dayOfWeek === Weekday.MONDAY); if (!monday) return; setSaved(false); setDays((prev) => prev.map((d) => (d.dayOfWeek === Weekday.MONDAY ? d : { ...d, isOff: monday.isOff, startTime: monday.startTime, endTime: monday.endTime }))); }; const handleSave = () => { setError(null); startTransition(async () => { const result = await saveWorkingHoursAction( days.map((d) => ({ dayOfWeek: d.dayOfWeek, isOff: d.isOff, ...(d.isOff ? {} : { startMinutes: toMinutes(d.startTime), endMinutes: toMinutes(d.endTime) }), })), ); if (!result.success) { setError(result.error ?? "Couldn't save working hours."); return; } setSaved(true); router.refresh(); }); }; return (
{days.map((day) => (
updateDay(day.dayOfWeek, { isOff: !checked })} aria-label={`${DAY_LABEL[day.dayOfWeek]} working`} />

{DAY_LABEL[day.dayOfWeek]}

Business hours: {businessHoursLabel[day.dayOfWeek]}

{day.isOff ? ( Off ) : (
updateDay(day.dayOfWeek, { startTime: e.target.value })} className="rounded-lg border border-line px-2 py-1.5 text-xs" aria-label={`${DAY_LABEL[day.dayOfWeek]} start time`} /> to updateDay(day.dayOfWeek, { endTime: e.target.value })} className="rounded-lg border border-line px-2 py-1.5 text-xs" aria-label={`${DAY_LABEL[day.dayOfWeek]} end time`} />
)}
))}
{error && (

{error}

)} {saved && !error && (

Saved.

)}
); }