refactor(ui): move 62 hand-written empty states onto EmptyState

The admin sections, the cycle, illness, medication, mood, records and
settings cards, the pickers and dialogs said nothing-here-yet in a
hand-written muted paragraph in five sizes and three alignments. List
and section states now render through EmptyState (plain, compact; the
three with a next step carry it as the action), and the six chart
bodies through ChartEmptyState at their former height. The thirteen
that stay are a field without a value or a hint inside an editor, not
a list state. The ratchet ceiling drops from 75 to 13.
This commit is contained in:
Marc-André Bombeck committed 2026-10-20 13:31:02 +02:00
1 parent fe021c0ffd
commit e7ee416e19
56 files changed
+353 -224

No files matched your search

@@ -32,6 +32,7 @@ import { dateKeyOfInstant } from "../day/day-url";
import { formatMetricValue } from "./format-value";
import type { CustomMetricEntryDto } from "./types";
import { Segmented } from "@/components/ui/segmented";
import { ChartEmptyState } from "@/components/charts/chart-empty-state";
/**
* v1.25.5 — per-custom-metric trend chart, in the dashboard's visual language.
@@ -151,9 +152,7 @@ export function CustomMetricChart({
</div>
{points.length === 0 ? (
<p className="text-muted-foreground py-10 text-center text-sm">
{t("customMetrics.chart.empty")}
</p>
<ChartEmptyState title={t("customMetrics.chart.empty")} height={160} />
) : (
<div>
<div
@@ -21,6 +21,7 @@ import { queryKeys } from "@/lib/query-keys";
import { CustomMetricForm } from "./custom-metric-form";
import { formatMetricValue } from "./format-value";
import type { CustomMetricDto, CustomMetricListResponse } from "./types";
import { EmptyState } from "@/components/ui/empty-state";
/**
* v1.25.5 — inline list of the user's custom metrics, mounted ON the
@@ -99,12 +100,10 @@ export function CustomMetricList() {
onRetry={() => refetch()}
/>
) : metrics.length === 0 ? (
<Card>
<CardContent className="flex flex-col items-center gap-3 py-6 text-center">
<Gauge className="text-muted-foreground size-6" />
<p className="text-muted-foreground text-sm">
{t("customMetrics.emptyDescription")}
</p>
<EmptyState
icon={<Gauge className="size-6" />}
title={t("customMetrics.emptyDescription")}
action={
<Button
size="sm"
onClick={() => setAddOpen(true)}
@@ -112,8 +111,8 @@ export function CustomMetricList() {
>
{t("customMetrics.add")}
</Button>
</CardContent>
</Card>
}
/>
) : (
<Card>
<CardContent className="divide-border divide-y p-0">
@@ -17,6 +17,7 @@ import type {
CustomMetricEntryDto,
CustomMetricEntryListResponse,
} from "./types";
import { EmptyState } from "@/components/ui/empty-state";
const ENTRIES_PAGE_SIZE = 200;
@@ -90,9 +91,11 @@ export function CustomMetricValuesList({
if (entries.length === 0) {
return (
<p className="text-muted-foreground py-8 text-center text-sm">
{t("customMetrics.detail.emptyTitle")}
</p>
<EmptyState
variant="plain"
size="compact"
title={t("customMetrics.detail.emptyTitle")}
/>
);
}