Files
temetro/frontend/components/prescriptions/prescription-detail-sheet.tsx
T
Khalid Abdi e0de20b551 i18n: convert feature pages, dialogs, auth sub-pages and nav to t()
Move all hardcoded UI strings in the appointments, prescriptions, tasks,
messages, activity, analysis and patients views (plus their dialogs and
detail sheets), the remaining auth pages (verify-email, forgot/reset
password, accept-invite, onboarding), the clinic form and the sidebar user
menu into i18next keys in en/translation.json. Clinical option values
(appointment types, frequencies) stay canonical. English-only; no new
locale yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:57:00 +03:00

127 lines
4.5 KiB
TypeScript

"use client";
import { useTranslation } from "react-i18next";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import {
Sheet,
SheetHeader,
SheetPanel,
SheetPopup,
SheetTitle,
} from "@/components/ui/sheet";
import type { Prescription, RxStatus } from "@/components/prescriptions/prescriptions-view";
import { formatPrescribedAt } from "@/lib/prescriptions";
const statusVariant: Record<
RxStatus,
"default" | "secondary" | "destructive" | "outline"
> = {
active: "default",
completed: "outline",
expired: "destructive",
};
// Right-side Sheet showing one prescription's full detail, opened by clicking a
// row in the Prescriptions list (mirrors the Patients table → side Sheet
// pattern). The selected record is passed in from the page.
export function PrescriptionDetailSheet({
rx,
open,
onOpenChange,
}: {
rx: Prescription | null;
open: boolean;
onOpenChange: (open: boolean) => void;
}) {
const { t } = useTranslation();
return (
<Sheet onOpenChange={onOpenChange} open={open}>
<SheetPopup className="sm:max-w-xl" side="right">
<SheetHeader>
<SheetTitle>
{rx
? `${rx.medication}${rx.dose ? ` · ${rx.dose}` : ""}`
: t("prescriptions.detail.fallbackTitle")}
</SheetTitle>
</SheetHeader>
<SheetPanel className="min-h-0 flex-1">
{rx && (
<div className="flex flex-col gap-5">
<div className="flex items-center gap-3">
<Avatar className="size-10">
<AvatarFallback>{rx.initials}</AvatarFallback>
</Avatar>
<div className="flex min-w-0 flex-col">
<span className="truncate font-medium text-foreground text-sm">
{rx.name}
</span>
<span className="text-muted-foreground text-xs">
{t("prescriptions.detail.fileNumber", {
number: rx.fileNumber,
})}
</span>
</div>
<Badge className="ms-auto" variant={statusVariant[rx.status]}>
{t(`prescriptions.status.${rx.status}`)}
</Badge>
</div>
<dl className="grid grid-cols-[7rem_1fr] gap-x-3 gap-y-2 text-sm">
<dt className="text-muted-foreground">
{t("prescriptions.detail.medication")}
</dt>
<dd className="text-foreground">{rx.medication}</dd>
{rx.dose && (
<>
<dt className="text-muted-foreground">
{t("prescriptions.detail.dose")}
</dt>
<dd className="text-foreground">{rx.dose}</dd>
</>
)}
<dt className="text-muted-foreground">
{t("prescriptions.detail.frequency")}
</dt>
<dd className="text-foreground">{rx.frequency}</dd>
<dt className="text-muted-foreground">
{t("prescriptions.detail.duration")}
</dt>
<dd className="text-foreground">{rx.duration || "—"}</dd>
<dt className="text-muted-foreground">
{t("prescriptions.detail.prescriber")}
</dt>
<dd className="text-foreground">{rx.prescriber}</dd>
<dt className="text-muted-foreground">
{t("prescriptions.detail.date")}
</dt>
<dd className="text-foreground">
{formatPrescribedAt(rx.prescribedAt)}
</dd>
<dt className="text-muted-foreground">
{t("prescriptions.detail.status")}
</dt>
<dd className="text-foreground">
{t(`prescriptions.status.${rx.status}`)}
</dd>
</dl>
{rx.notes && (
<div className="flex flex-col gap-1.5">
<span className="text-muted-foreground text-xs">
{t("prescriptions.detail.notes")}
</span>
<p className="whitespace-pre-wrap text-foreground text-sm leading-relaxed">
{rx.notes}
</p>
</div>
)}
</div>
)}
</SheetPanel>
</SheetPopup>
</Sheet>
);
}