"use client"; import { useQuery } from "@tanstack/react-query"; import { LayoutGrid, Loader2, Pill } from "lucide-react"; import { MedicationOrderEditor, type ReorderMedication, } from "@/components/medications/medication-order-editor"; import { MedicationViewToggle } from "@/components/medications/medication-view-toggle"; import { SettingsCard } from "@/components/settings/settings-card"; import { SettingsCardHeader } from "@/components/settings/_card-header"; import { InjectionSitesCard } from "@/components/settings/injection-sites-card"; import { useAuth } from "@/hooks/use-auth"; import { apiGet } from "@/lib/api/api-fetch"; import { useTranslations } from "@/lib/i18n/context"; import { applyMedicationOrder } from "@/lib/medications/medication-order"; import { queryKeys } from "@/lib/query-keys"; import { useMedicationListLayout } from "@/lib/queries/use-medication-list-layout"; /** * v1.16.10 — the "Medikamente" settings section. v1.18.0 (S5) promoted it * from a Layout-hub child to its own standalone nav entry and gathered the * medication-specific preferences here. v1.18.1 (D3) made medications a * toggleable fail-open module, so this nav entry hides when the account * turns the module off (the medication data routes stay live). Hosts three * blocks: * 1. The list VIEW preference — cards vs table, written optimistically * through the same `PUT /api/medications/layout` the page header * toggle uses (the toggle component is shared). * 2. The manual ORDER editor — two grouped lists (Aktiv / Inaktiv) * with drag + arrow reordering, flushed by an explicit Save, * persisted as active-ids-then-inactive-ids on the same layout row. * 3. Injection-site exclusions — moved here from the account profile so * every medication-specific preference lives on one screen. * * The list view + order both write through the same `/api/medications/layout` * contract the /medications page reads, so a save here repaints both views. */ /** The slice of the medications list the order editor needs. */ interface MedicationListEntry { id: string; name: string; dose: string; active: boolean; } export function MedicationsSection() { const { t } = useTranslations(); const { isAuthenticated } = useAuth(); const { layout, isLayoutLoading, setView } = useMedicationListLayout(); const { data: medications, isLoading } = useQuery({ queryKey: queryKeys.medications(), queryFn: async () => { return apiGet("/api/medications"); }, }); // Defensive against stale service-worker responses or any future API // shape change: only map when we actually have an array. The editor // receives the page's current effective order (active block first, // inactive after) so it opens showing exactly what both views render. const medsArray = Array.isArray(medications) ? medications : []; const ordered: ReorderMedication[] = [ ...applyMedicationOrder( medsArray.filter((m) => m.active), layout.order, ), ...applyMedicationOrder( medsArray.filter((m) => !m.active), layout.order, ), ].map((m) => ({ id: m.id, name: m.name, dose: m.dose, active: m.active })); // v1.18.6 (W9) — the visible heading + subtitle now come from the shared // `` in the route; this body is the medication cards. return (
{/* View preference — cards vs table. The shared header toggle writes optimistically, so there is no Save button here. */}

{t("medications.viewToggleHint")}

{isLayoutLoading ? ( ) : ( )}
{/* Manual order — applies to both list views. */} {isLoading || isLayoutLoading ? (
{t("common.loading")}
) : ( )}
{/* v1.18.0 (S5) — injection-site exclusions are a medication setting; they moved here from the account profile so all medication-specific preferences live in one place. */}
); }