"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Calendar, Clock, Phone, Mail } from "lucide-react"; import { toast } from "sonner"; type Appointment = { id: string; date: Date; timeSlot: string; status: string; notes: string | null; patient: { name: string; email: string; phone: string | null; medicalHistory: string | null; }; service: { name: string; duration: number; price: number; }; payment: { status: string; } | null; }; type DentistAppointmentsListProps = { appointments: Appointment[]; }; export function DentistAppointmentsList({ appointments, }: DentistAppointmentsListProps) { const router = useRouter(); const [isLoading, setIsLoading] = useState(null); const pendingAppointments = appointments.filter( (apt) => apt.status === "pending" ); const upcomingAppointments = appointments.filter( (apt) => new Date(apt.date) >= new Date() && apt.status === "confirmed" ); const completedAppointments = appointments.filter( (apt) => apt.status === "completed" ); const handleConfirmAppointment = async (appointmentId: string) => { setIsLoading(appointmentId); try { const response = await fetch(`/api/appointments/${appointmentId}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ status: "confirmed", }), }); if (!response.ok) { throw new Error("Failed to confirm appointment"); } toast.success("Appointment confirmed successfully"); router.refresh(); } catch (error) { console.error(error); toast.error("Failed to confirm appointment"); } finally { setIsLoading(null); } }; const handleDeclineAppointment = async (appointmentId: string) => { if (!confirm("Are you sure you want to decline this appointment?")) { return; } setIsLoading(appointmentId); try { const response = await fetch(`/api/appointments/${appointmentId}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ status: "cancelled", cancelReason: "Declined by dentist", }), }); if (!response.ok) { throw new Error("Failed to decline appointment"); } toast.success("Appointment declined"); router.refresh(); } catch (error) { console.error(error); toast.error("Failed to decline appointment"); } finally { setIsLoading(null); } }; const handleCompleteAppointment = async (appointmentId: string) => { setIsLoading(appointmentId); try { const response = await fetch(`/api/appointments/${appointmentId}`, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ status: "completed", }), }); if (!response.ok) { throw new Error("Failed to complete appointment"); } toast.success("Appointment marked as completed"); router.refresh(); } catch (error) { console.error(error); toast.error("Failed to complete appointment"); } finally { setIsLoading(null); } }; const getStatusBadge = (status: string) => { const variants: Record< string, "default" | "secondary" | "destructive" | "outline" > = { pending: "secondary", confirmed: "default", cancelled: "destructive", completed: "outline", rescheduled: "secondary", }; return ( {status.toUpperCase()} ); }; const renderAppointmentCard = ( appointment: Appointment, showActions: boolean = true ) => (
{appointment.patient.name} {appointment.service.name}
{getStatusBadge(appointment.status)}
{new Date(appointment.date).toLocaleDateString()}
{appointment.timeSlot}
{appointment.patient.phone && (
{appointment.patient.phone}
)}
{appointment.patient.email}
{appointment.patient.medicalHistory && (

Medical History:

{appointment.patient.medicalHistory}

)} {appointment.notes && (

Patient Notes:

{appointment.notes}

)} {showActions && (
{appointment.status === "pending" && ( <> )} {appointment.status === "confirmed" && ( )}
)}
); return ( Pending ({pendingAppointments.length}) Upcoming ({upcomingAppointments.length}) Completed ({completedAppointments.length}) {pendingAppointments.length === 0 ? (

No pending appointments

) : ( pendingAppointments.map((apt) => renderAppointmentCard(apt)) )}
{upcomingAppointments.length === 0 ? (

No upcoming appointments

) : ( upcomingAppointments.map((apt) => renderAppointmentCard(apt)) )}
{completedAppointments.length === 0 ? (

No completed appointments

) : ( completedAppointments.map((apt) => renderAppointmentCard(apt, false)) )}
); }