mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
The two consoles used the same primitives and still read as two systems, because everything without a primitive had drifted: the header-to-body step existed in three competing techniques at once (`mt-4` on the first body child, `space-y-4` on the card, `mb-4` on the header), the body started either at the card edge or 28 px in, and both shells hand-rolled the page title instead of calling `PageHeader`. Move the decisions into the primitives so a call site cannot re-open them: - `SettingsCard` is gap-based like `Card` (`flex flex-col gap-4`). The header-to-body step is the container's, not a margin somebody remembers. A dense card still overrides the gap on the card itself. - The body starts at the card edge. `pl-7` is gone — off the spacing scale, and it mis-aligned action rows against their own forms wherever two neighbouring cards disagreed about it. - The card header's description slot loses its `space-y-1`. That was the licence call sites used to stack explainer paragraphs into a muted `text-xs` slot; the slot holds one sentence. - New `SettingsCardActions`: one action row, trailing edge, last thing in the card. `align="start"` spells the one exception, a card whose only actions are links out. - New `StatTile` replaces four hand-rolled label/value boxes in Admin. - `SectionHeading` moves from `insights/` to `ui/`. It is the heading above a group of cards, which is what Settings needs; Settings had been using a card header with no card, which reads as a card that failed to paint. Both shells now render their heading through `PageHeader`, which gained `headingAs="div"` for the second copy each shell paints (mobile above the nav strip, desktop inside the grid) so only one is a real `<h1>`. The page explainer is muted everywhere: the primitive said foreground, the standards and every hand-rolled copy said muted, so pages disagreed with each other. Medications, Vorsorge, the labs / custom-metric / illness detail pages and the clinician view drop their hand-rolled title blocks too, including the mid-word truncation on the medications subtitle. Tests pin the parts that can be checked exactly: the card's gap, the description slot's missing rhythm, the action row's two alignments, the `<h1>`-free shells, and a sweep asserting `pl-7` stays gone.
78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { Archive, Folders, Loader2, Tags } from "lucide-react";
|
|
|
|
import { SettingsCard } from "@/components/settings/settings-card";
|
|
import { SettingsCardHeader } from "@/components/settings/_card-header";
|
|
import { ArchivedTagsCard } from "@/components/mood/manage/archived-tags-card";
|
|
import { TagGroupsCard } from "@/components/mood/manage/tag-groups-card";
|
|
import { TagManagerCard } from "@/components/mood/manage/tag-manager-card";
|
|
import { useMoodTagManage } from "@/components/mood/manage/use-mood-tag-manage";
|
|
import { useAuth } from "@/hooks/use-auth";
|
|
import { useTranslations } from "@/lib/i18n/context";
|
|
|
|
/**
|
|
* v1.17 — the "Stimmungs-Tags" settings section (`/settings/mood`),
|
|
* following the medications-section card pattern. Hosts the whole
|
|
* mood-tag management surface in three blocks:
|
|
* 1. Groups — create / rename / delete own groups, drag + arrow
|
|
* reorder of the picker's group order.
|
|
* 2. Tags — per-group tag list mirroring the picker: hide/show
|
|
* catalogue tags, edit / move / archive custom tags, drag + arrow
|
|
* reorder, create.
|
|
* 3. Archived — archived custom tags with restore and the explicit
|
|
* hard-delete path.
|
|
*
|
|
* One management read (`useMoodTagManage`) feeds all three cards — the
|
|
* section never waterfalls; every mutation invalidates the
|
|
* `["mood-tag-catalog"]` prefix so the mood form's picker repaints in
|
|
* the same tick.
|
|
*/
|
|
|
|
export function MoodSection() {
|
|
const { t } = useTranslations();
|
|
const { isAuthenticated } = useAuth();
|
|
const { data: catalog, isLoading } = useMoodTagManage(isAuthenticated);
|
|
|
|
const loading = (
|
|
<div className="text-muted-foreground flex items-center gap-2 text-sm">
|
|
<Loader2 className="h-4 w-4 animate-spin motion-reduce:animate-none" />
|
|
{t("common.loading")}
|
|
</div>
|
|
);
|
|
|
|
// v1.18.6 (W9) — the visible heading + subtitle now come from the shared
|
|
// `<SettingsSectionFrame>` in the route; this body is the mood-tag cards.
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Groups — picker group order + own groups. */}
|
|
<SettingsCard id="mood-groups" className="scroll-mt-28">
|
|
<SettingsCardHeader
|
|
icon={Folders}
|
|
title={t("mood.manage.groupsTitle")}
|
|
/>
|
|
{isLoading || !catalog ? loading : <TagGroupsCard catalog={catalog} />}
|
|
</SettingsCard>
|
|
|
|
{/* Tags — visibility, order, edit, move, create. */}
|
|
<SettingsCard id="mood-tags" className="scroll-mt-28">
|
|
<SettingsCardHeader icon={Tags} title={t("mood.manage.tagsTitle")} />
|
|
{isLoading || !catalog ? loading : <TagManagerCard catalog={catalog} />}
|
|
</SettingsCard>
|
|
|
|
{/* Archived custom tags — restore / hard delete. */}
|
|
<SettingsCard id="mood-archived" className="scroll-mt-28">
|
|
<SettingsCardHeader
|
|
icon={Archive}
|
|
title={t("mood.manage.archivedTitle")}
|
|
/>
|
|
{isLoading || !catalog ? (
|
|
loading
|
|
) : (
|
|
<ArchivedTagsCard catalog={catalog} />
|
|
)}
|
|
</SettingsCard>
|
|
</div>
|
|
);
|
|
}
|