import { useTranslation } from "react-i18next"; import { useEscapeKey } from "../../hooks/useEscapeKey"; import type { IntakeJournalEntry, IntakeJournalHistoryFilters } from "../../hooks/useIntakeJournal"; import { useScrollLock } from "../../hooks/useScrollLock"; import type { Medication } from "../../types"; import { formatDateTime, getNumericLocale } from "../../utils/formatters"; import { DateTimeInput } from "../DateTimeInput"; import { MedicationAvatar } from "../MedicationAvatar"; interface IntakeJournalHistoryModalProps { isOpen: boolean; entries: IntakeJournalEntry[]; filters: IntakeJournalHistoryFilters; medications: Medication[]; isLoading: boolean; error: string | null; onClose: () => void; onFilterChange: (patch: Partial) => void; onReload: () => Promise | void; onResetFilters: () => void; onReopen: (doseId: string) => Promise | void; } function formatDisplayDateTime(value: string | null): string | null { if (!value) { return null; } return formatDateTime(value, getNumericLocale()); } function getJournalSourceLabel(entry: IntakeJournalEntry, t: ReturnType["t"]): string { if (entry.takenSource === "automatic") { return t("journal.context.sourceAutomaticReminder"); } return entry.markedBy ? t("journal.context.sourceSharedLink") : t("journal.context.sourceOwnerApp"); } export function IntakeJournalHistoryModal({ isOpen, entries, filters, medications, isLoading, error, onClose, onFilterChange, onReload, onResetFilters, onReopen, }: IntakeJournalHistoryModalProps) { const { t } = useTranslation(); useScrollLock(isOpen); useEscapeKey(isOpen, onClose); if (!isOpen) { return null; } let listContent: React.ReactNode; if (isLoading) { listContent =
{t("journal.history.loading")}
; } else if (entries.length === 0) { listContent =
{t("journal.history.empty")}
; } else { listContent = entries.map((entry) => (
{entry.medicationName}

{formatDisplayDateTime(entry.scheduledFor) ?? t("common.notAvailable")}

{entry.note ?? t("journal.history.noNote")}

{t(entry.dismissed ? "journal.context.statusSkipped" : "journal.context.statusTaken")} {getJournalSourceLabel(entry, t)} {entry.updatedAt && ( {t("journal.history.updatedAt", { date: formatDisplayDateTime(entry.updatedAt) ?? entry.updatedAt, })} )}
)); } return (
{ if (event.key !== "Escape") { event.stopPropagation(); } }} >
event.stopPropagation()} onKeyDown={(event) => { if (event.key !== "Escape") { event.stopPropagation(); } }} >

{t("journal.history.title")}

{t("journal.history.description")}

{t("journal.history.filters.from")} onFilterChange({ from: event.target.value })} step="60" aria-label={t("journal.history.filters.from")} placeholder={t("journal.history.filters.fromPlaceholder")} />
{t("journal.history.filters.to")} onFilterChange({ to: event.target.value })} step="60" aria-label={t("journal.history.filters.to")} placeholder={t("journal.history.filters.toPlaceholder")} />
{error &&
{error}
}
{listContent}
); }