import { useState } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; import { Delete, Edit, Eye, MoreVertical } from "lucide-react"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { PatientUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas"; import {z} from "zod"; const PatientSchema = (PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject).omit({ appointments: true, }); type Patient = z.infer; interface PatientTableProps { patients: Patient[]; onEdit: (patient: Patient) => void; onView: (patient: Patient) => void; onDelete: (patient: Patient) => void; } export function PatientTable({ patients, onEdit, onView, onDelete }: PatientTableProps) { const [currentPage, setCurrentPage] = useState(1); const patientsPerPage = 5; // Get current patients const indexOfLastPatient = currentPage * patientsPerPage; const indexOfFirstPatient = indexOfLastPatient - patientsPerPage; const currentPatients = patients.slice(indexOfFirstPatient, indexOfLastPatient); const totalPages = Math.ceil(patients.length / patientsPerPage); const getInitials = (firstName: string, lastName: string) => { return (firstName.charAt(0) + lastName.charAt(0)).toUpperCase(); }; const getAvatarColor = (id: number) => { const colorClasses = [ "bg-blue-500", "bg-teal-500", "bg-amber-500", "bg-rose-500", "bg-indigo-500", "bg-green-500", "bg-purple-500", ]; // This returns a literal string from above — not a generated string return colorClasses[id % colorClasses.length]; }; const formatDate = (dateString: string | Date) => { const date = new Date(dateString); return new Intl.DateTimeFormat('en-US', { day: '2-digit', month: 'short', year: 'numeric' }).format(date); }; return (
Patient DOB / Gender Contact Insurance Status Actions {currentPatients.length === 0 ? ( No patients found. Add your first patient to get started. ) : ( currentPatients.map((patient) => (
{getInitials(patient.firstName, patient.lastName)}
{patient.firstName} {patient.lastName}
PID-{patient.id.toString().padStart(4, '0')}
{formatDate(patient.dateOfBirth)}
{patient.gender}
{patient.phone}
{patient.email}
{patient.insuranceProvider ? ( patient.insuranceProvider === 'delta' ? 'Delta Dental' : patient.insuranceProvider === 'metlife' ? 'MetLife' : patient.insuranceProvider === 'cigna' ? 'Cigna' : patient.insuranceProvider === 'aetna' ? 'Aetna' : patient.insuranceProvider === 'none' ? 'No Insurance' : patient.insuranceProvider ) : ( 'Not specified' )}
{patient.insuranceId && (
ID: {patient.insuranceId}
)}
{patient.status}
)) )}
{patients.length > patientsPerPage && (

Showing {indexOfFirstPatient + 1} to{" "} {Math.min(indexOfLastPatient, patients.length)} {" "} of {patients.length} results

{ e.preventDefault(); if (currentPage > 1) setCurrentPage(currentPage - 1); }} className={currentPage === 1 ? "pointer-events-none opacity-50" : ""} /> {Array.from({ length: totalPages }).map((_, i) => ( { e.preventDefault(); setCurrentPage(i + 1); }} isActive={currentPage === i + 1} > {i + 1} ))} { e.preventDefault(); if (currentPage < totalPages) setCurrentPage(currentPage + 1); }} className={currentPage === totalPages ? "pointer-events-none opacity-50" : ""} />
)}
); }