"use client"; import { CalendarClock, ChevronRight, ClipboardList, Pill } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import Link from "next/link"; import { useTranslation } from "react-i18next"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import type { Appointment } from "@/lib/appointments"; import { formatPrescribedAt, type Prescription } from "@/lib/prescriptions"; import type { Task } from "@/lib/tasks"; type Row = { primary: string; secondary?: string; badge?: string }; function Shell({ icon: Icon, title, rows, emptyKey, }: { icon: LucideIcon; title: string; rows: Row[]; emptyKey: string; }) { const { t } = useTranslation(); return (
{title} {rows.length}
{rows.length === 0 ? (

{t(emptyKey)}

) : (
{rows.map((row, i) => (
{row.primary} {row.secondary ? ( {row.secondary} ) : null}
{row.badge ? ( {row.badge} ) : null}
))}
)}
); } // "2026-06-16" -> "Jun 16" (compact, for the date-range summary). function shortDate(iso: string): string { return new Date(`${iso}T00:00:00`).toLocaleDateString("en-US", { month: "short", day: "numeric", }); } // Appointments are rendered condensed: rather than one dense card per row (which // floods the chat for a week's schedule), show a small summary + a few previews // and send the clinician to the Appointments calendar for the full picture. const APPT_PREVIEW = 3; export function AppointmentListCard({ appointments, }: { appointments: Appointment[]; }) { const { t } = useTranslation(); if (appointments.length === 0) { return ( ); } const dates = appointments.map((a) => a.date).filter(Boolean).sort(); const first = dates[0]; const last = dates[dates.length - 1]; const range = first ? first === last ? shortDate(first) : `${shortDate(first)} – ${shortDate(last as string)}` : ""; // Deep-link to the Appointments calendar, opened on the first appointment's // month (the page reads `?calendar=1&date=`). const href = first ? `/appointments?calendar=1&date=${first}` : "/appointments?calendar=1"; const preview = appointments.slice(0, APPT_PREVIEW); const remaining = appointments.length - preview.length; return (
{t("chat.lists.appointments")} {range ? ( {range} ) : null} {appointments.length}
{preview.map((a, i) => (
{a.time}
{a.name} {[shortDate(a.date), a.type, a.provider] .filter(Boolean) .join(" · ")}
{a.status}
))}
{remaining > 0 ? t("chat.lists.moreAppointments", { count: remaining }) : ""}
); } export function TaskListCard({ tasks }: { tasks: Task[] }) { const { t } = useTranslation(); const rows: Row[] = tasks.map((tk) => ({ primary: tk.title, secondary: [tk.assignee, tk.due].filter(Boolean).join(" · "), badge: tk.done ? t("chat.lists.done") : tk.priority, })); return ( ); } export function PrescriptionListCard({ prescriptions, }: { prescriptions: Prescription[]; }) { const { t } = useTranslation(); const rows: Row[] = prescriptions.map((rx) => ({ primary: [rx.medication, rx.dose].filter(Boolean).join(" "), secondary: [rx.name, rx.frequency, formatPrescribedAt(rx.prescribedAt)] .filter(Boolean) .join(" · "), badge: rx.status, })); return ( ); }