import { format } from "date-fns"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { MoreHorizontal, Edit, Trash2, Eye, Calendar, Clock, } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; // import { Appointment, Patient } from "@repo/db/shared/schemas"; import { AppointmentUncheckedCreateInputObjectSchema, PatientUncheckedCreateInputObjectSchema, } from "@repo/db/shared/schemas"; import { z } from "zod"; type Appointment = z.infer; const PatientSchema = ( PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject ).omit({ appointments: true, }); type Patient = z.infer; interface AppointmentTableProps { appointments: Appointment[]; patients: Patient[]; onEdit: (appointment: Appointment) => void; onDelete: (id: number) => void; } export function AppointmentTable({ appointments, patients, onEdit, onDelete, }: AppointmentTableProps) { // Helper function to get patient name const getPatientName = (patientId: number) => { const patient = patients.find((p) => p.id === patientId); return patient ? `${patient.firstName} ${patient.lastName}` : "Unknown Patient"; }; // Helper function to get status badge const getStatusBadge = (status: string) => { const statusConfig: Record< string, { variant: | "default" | "secondary" | "destructive" | "outline" | "success"; label: string; } > = { scheduled: { variant: "default", label: "Scheduled" }, confirmed: { variant: "secondary", label: "Confirmed" }, completed: { variant: "success", label: "Completed" }, cancelled: { variant: "destructive", label: "Cancelled" }, "no-show": { variant: "outline", label: "No Show" }, }; const config = statusConfig[status] || { variant: "default", label: status, }; return {config.label}; }; // Sort appointments by date and time (newest first) const sortedAppointments = [...appointments].sort((a, b) => { const dateComparison = new Date(b.date).getTime() - new Date(a.date).getTime(); if (dateComparison !== 0) return dateComparison; return a.startTime.toString().localeCompare(b.startTime.toString()); }); return (
Patient Date Time Type Status Actions {sortedAppointments.length === 0 ? ( No appointments found. ) : ( sortedAppointments.map((appointment) => ( {getPatientName(appointment.patientId)}
{format(new Date(appointment.date), "MMM d, yyyy")}
{appointment.startTime.slice(0, 5)} -{" "} {appointment.endTime.slice(0, 5)}
{appointment.type.replace("-", " ")} {getStatusBadge(appointment.status!)} Actions onEdit(appointment)}> Edit { if (typeof appointment.id === "number") { onDelete(appointment.id); } else { console.error("Invalid appointment ID"); } }} className="text-destructive focus:text-destructive" > Delete
)) )}
); }