import { Show, createSignal, createMemo } from "solid-js"; import { Input } from "../../components/ui/input"; import { Select } from "../../components/ui/select"; import { Textarea } from "../../components/ui/textarea"; import { getInitials } from "../../components/dashboard/types"; import { CalendarDaysIcon, PlusIcon, XIcon, EyeIcon } from "../../components/dashboard/icons"; import { apiClient } from "../../lib/api-client"; import { DashboardLayout, useDashboardData } from "./layout"; function BookingsPage() { const data = useDashboardData(); const [filterStatus, setFilterStatus] = createSignal<"all" | "confirmed" | "pending" | "cancelled" | "completed">("all"); const [filterDateRange, setFilterDateRange] = createSignal<"all" | "today" | "week" | "month">("all"); const [searchQuery, setSearchQuery] = createSignal(""); const [showNewBooking, setShowNewBooking] = createSignal(false); const [creatingBooking, setCreatingBooking] = createSignal(false); const [pinnedBookingIds, setPinnedBookingIds] = createSignal>(new Set()); const [newBookingCustomer, setNewBookingCustomer] = createSignal(""); const [newBookingEmail, setNewBookingEmail] = createSignal(""); const [newBookingService, setNewBookingService] = createSignal(""); const [newBookingDate, setNewBookingDate] = createSignal(""); const [newBookingTime, setNewBookingTime] = createSignal(""); const [newBookingNotes, setNewBookingNotes] = createSignal(""); const resolvedAllBookings = () => data.resolvedSummary()?.allBookings ?? data.normalizedAllBookings() ?? []; const filteredBookings = createMemo(() => { let bookings = resolvedAllBookings(); if (filterStatus() !== "all") bookings = bookings.filter((b: any) => b.status === filterStatus()); const now = new Date(); if (filterDateRange() === "today") bookings = bookings.filter((b: any) => new Date(b.startsAt).toDateString() === now.toDateString()); else if (filterDateRange() === "week") { const weekEnd = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); bookings = bookings.filter((b: any) => { const d = new Date(b.startsAt); return d >= now && d <= weekEnd; }); } else if (filterDateRange() === "month") { const monthEnd = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000); bookings = bookings.filter((b: any) => { const d = new Date(b.startsAt); return d >= now && d <= monthEnd; }); } if (searchQuery().trim()) { const q = searchQuery().toLowerCase(); bookings = bookings.filter((b: any) => b.customerName?.toLowerCase().includes(q) || b.service?.toLowerCase().includes(q) || b.reference?.toLowerCase().includes(q) ); } return bookings.sort((a: any, b: any) => { const aPinned = pinnedBookingIds().has(a.id) ? 1 : 0; const bPinned = pinnedBookingIds().has(b.id) ? 1 : 0; if (aPinned !== bPinned) return bPinned - aPinned; return new Date(b.startsAt).getTime() - new Date(a.startsAt).getTime(); }); }); const bookingStats = createMemo(() => { const bookings = resolvedAllBookings(); return { total: bookings.length, confirmed: bookings.filter((b: any) => b.status === "confirmed").length, pending: bookings.filter((b: any) => b.status === "pending").length, cancelled: bookings.filter((b: any) => b.status === "cancelled").length, completed: bookings.filter((b: any) => b.status === "completed").length, }; }); const handleCreateBooking = async () => { const bearer = data.token(); if (!bearer || bearer.startsWith("demo.")) { data.setDemoNotice(data.i18n.locale() === "cs" ? "V demo rezimu nelze vytvaret rezervace." : "Cannot create bookings in demo mode."); setShowNewBooking(false); return; } setCreatingBooking(true); try { await (apiClient as any).POST("/v1/catalog/bookings", { headers: { Authorization: `Bearer ${bearer}` }, body: { customerName: newBookingCustomer(), customerEmail: newBookingEmail(), service: newBookingService(), startsAt: new Date(`${newBookingDate()}T${newBookingTime()}`).toISOString(), notes: newBookingNotes() } }); setNewBookingCustomer(""); setNewBookingEmail(""); setNewBookingService(""); setNewBookingDate(""); setNewBookingTime(""); setNewBookingNotes(""); setShowNewBooking(false); } catch { data.setDemoNotice(data.i18n.locale() === "cs" ? "Vytvoreni rezervace selhalo." : "Failed to create booking."); } finally { setCreatingBooking(false); } }; const statusLabels: Record = { confirmed: data.i18n.t("dashboard.confirmed"), pending: data.i18n.t("dashboard.pending"), cancelled: data.i18n.t("dashboard.cancelled"), completed: data.i18n.t("dashboard.completed") }; return (

{data.i18n.t("dashboard.bookingManagement")}

{bookingStats().total} {data.i18n.t("dashboard.totalBookings")}

{/* Stats */}
{[ { key: "confirmed", label: data.i18n.t("dashboard.confirmed"), value: bookingStats().confirmed }, { key: "pending", label: data.i18n.t("dashboard.pending"), value: bookingStats().pending }, { key: "cancelled", label: data.i18n.t("dashboard.cancelled"), value: bookingStats().cancelled }, { key: "completed", label: data.i18n.t("dashboard.completed"), value: bookingStats().completed }, ].map((s) => ( ))}
{/* Filters */}
setSearchQuery(e.currentTarget.value)} />
setFilterDateRange(v as any)} options={[ { value: "all", label: data.i18n.t("dashboard.filter.all") }, { value: "today", label: data.i18n.t("dashboard.filter.today") }, { value: "week", label: data.i18n.t("dashboard.filter.week") }, { value: "month", label: data.i18n.t("dashboard.filter.month") }, ]} />
{/* Bookings List */}
0} fallback={

{data.i18n.t("dashboard.empty.title")}

{data.i18n.t("dashboard.empty.bookingsDesc")}

}>
{filteredBookings().map((booking: any) => { const isPinned = () => pinnedBookingIds().has(booking.id); const togglePin = (e: Event) => { e.stopPropagation(); setPinnedBookingIds((prev) => { const next = new Set(prev); if (next.has(booking.id)) next.delete(booking.id); else next.add(booking.id); return next; }); }; return (
{getInitials(booking.customerName)}

{booking.customerName}

{isPinned() && }

{booking.service} • {new Date(booking.startsAt).toLocaleDateString()} {new Date(booking.startsAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}

{statusLabels[booking.status]}
); })}
{/* New Booking Modal */}
setShowNewBooking(false)} />

{data.i18n.t("dashboard.newBooking")}

setNewBookingCustomer(e.currentTarget.value)} /> setNewBookingEmail(e.currentTarget.value)} /> setNewBookingService(e.currentTarget.value)} />
setNewBookingDate(e.currentTarget.value)} /> setNewBookingTime(e.currentTarget.value)} />