mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
The injection_site column on intake events was read across several surfaces but never written, so site tracking was effectively dead. Wire it end-to-end as a per-medication opt-in, gated on an INJECTION delivery form and default off. - Schema: add medications.track_injection_sites + allowed_injection_sites and users.global_excluded_injection_sites (migrations 0099, 0100; additive, defaulted, no backfill). - Intake write path: accept an optional injectionSite on the per-med, status-toggle, and bulk intake routes. Persist it only on a taken injection with tracking enabled, validated against the medication's effective allowed set (per-med allowed sites minus the user-level global exclusion, deny wins) — a disallowed site returns 422 (the bulk route skips the entry). - Rotation: extend the least-recently-used recommender with an allowed filter; the picker disables sites outside the effective set. - UI: per-medication tracking toggle + allowed-sites editor in the dose wizard step, a skippable post-dose site prompt on both medication cards, and a Settings card for the user-level global exclusion. - Contract: injectionSite is additive on the intake request; OpenAPI regenerated. New GET/PATCH /api/auth/me/injection-site-prefs. The site capture is always optional and never blocks logging a dose.
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import { DashboardLayoutSection } from "@/components/settings/dashboard-layout-section";
|
|
import { UnitPreferenceCard } from "@/components/settings/unit-preference-card";
|
|
import { InjectionSitesCard } from "@/components/settings/injection-sites-card";
|
|
import { useAuth } from "@/hooks/use-auth";
|
|
import { useTranslations } from "@/lib/i18n/context";
|
|
|
|
export function DashboardSection() {
|
|
const { t } = useTranslations();
|
|
const { isAuthenticated } = useAuth();
|
|
|
|
return (
|
|
<section
|
|
aria-labelledby="settings-section-dashboard-title"
|
|
className="space-y-6"
|
|
>
|
|
<header className="space-y-1">
|
|
<h1
|
|
id="settings-section-dashboard-title"
|
|
className="text-2xl font-semibold tracking-tight"
|
|
>
|
|
{t("settings.sections.dashboard.title")}
|
|
</h1>
|
|
<p className="text-muted-foreground text-sm">
|
|
{t("settings.sections.dashboard.description")}
|
|
</p>
|
|
</header>
|
|
|
|
<UnitPreferenceCard isAuthenticated={isAuthenticated} />
|
|
|
|
<InjectionSitesCard isAuthenticated={isAuthenticated} />
|
|
|
|
<DashboardLayoutSection id="dashboard-layout" />
|
|
</section>
|
|
);
|
|
}
|