"use client"; import { useState, useEffect } from "react"; import { Calendar, Clock, User, Video, FileText, MoreVertical, Search, } from "lucide-react"; import { useAppTheme } from "@/components/ThemeProvider"; import { listAppointments } from "@/lib/actions/appointments"; import { Input } from "@/components/ui/input"; import { toast } from "sonner"; import type { Appointment } from "@/lib/models/appointments"; export default function Booking() { const [appointments, setAppointments] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(""); const { theme } = useAppTheme(); const isDark = theme === "dark"; useEffect(() => { const fetchBookings = async () => { setLoading(true); try { const data = await listAppointments(); console.log("Fetched appointments:", data); console.log("Appointments count:", data?.length); setAppointments(data || []); } catch (error) { console.error("Failed to fetch appointments:", error); toast.error("Failed to load appointments. Please try again."); setAppointments([]); } finally { setLoading(false); } }; fetchBookings(); }, []); const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); }; const formatTime = (dateString: string) => { const date = new Date(dateString); return date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true, }); }; const getStatusColor = (status: string) => { const normalized = status.toLowerCase(); if (isDark) { switch (normalized) { case "scheduled": return "bg-blue-500/20 text-blue-200"; case "completed": return "bg-green-500/20 text-green-200"; case "rejected": case "cancelled": return "bg-red-500/20 text-red-200"; case "pending_review": case "pending": return "bg-yellow-500/20 text-yellow-200"; default: return "bg-gray-700 text-gray-200"; } } switch (normalized) { case "scheduled": return "bg-blue-100 text-blue-700"; case "completed": return "bg-green-100 text-green-700"; case "rejected": case "cancelled": return "bg-red-100 text-red-700"; case "pending_review": case "pending": return "bg-yellow-100 text-yellow-700"; default: return "bg-gray-100 text-gray-700"; } }; const formatStatus = (status: string) => { return status.replace("_", " ").replace(/\b\w/g, (l) => l.toUpperCase()); }; const filteredAppointments = appointments.filter( (appointment) => appointment.first_name .toLowerCase() .includes(searchTerm.toLowerCase()) || appointment.last_name .toLowerCase() .includes(searchTerm.toLowerCase()) || appointment.email.toLowerCase().includes(searchTerm.toLowerCase()) || (appointment.phone && appointment.phone.toLowerCase().includes(searchTerm.toLowerCase())) ); return (
{/* Main Content */}
{/* Page Header */}

Bookings

Manage and view all appointment bookings

{/* Search Bar */}
setSearchTerm(e.target.value)} className={`pl-10 ${isDark ? "bg-gray-800 border-gray-700 text-white placeholder:text-gray-400" : "bg-white border-gray-200 text-gray-900 placeholder:text-gray-500"}`} />
{loading ? (
) : filteredAppointments.length === 0 ? (

No bookings found

{searchTerm ? "Try adjusting your search terms" : "No appointments have been created yet"}

) : (
{filteredAppointments.map((appointment) => ( ))}
Patient Status Actions
{appointment.first_name} {appointment.last_name}
{appointment.phone && ( )} {appointment.scheduled_datetime && (
{formatDate(appointment.scheduled_datetime)}
)}
{appointment.scheduled_datetime ? ( <>
{formatDate(appointment.scheduled_datetime)}
{formatTime(appointment.scheduled_datetime)}
) : (
Not scheduled
)}
{formatStatus(appointment.status)}
{appointment.jitsi_meet_url && ( )} {appointment.reason && ( )}
)}
); }