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

@@ -16,6 +16,7 @@ import type { InboundDocumentDto } from "@/lib/validations/inbound-documents";
import { DOCUMENT_KIND_ICONS } from "@/components/documents/document-kind-meta";
import { QueryErrorRow } from "@/components/ui/query-error-row";
import { EmptyState } from "@/components/ui/empty-state";
/**
* v1.29.x (S7) — the "Choose from documents" picker for attaching stored vault
@@ -190,9 +191,11 @@ export function AttachmentPicker({
onRetry={() => void list.refetch()}
/>
) : documents.length === 0 ? (
<p className="text-muted-foreground py-6 text-center text-sm">
{t("insights.coach.attach.pickerEmpty")}
</p>
<EmptyState
variant="plain"
size="compact"
title={t("insights.coach.attach.pickerEmpty")}
/>
) : (
<ul className="max-h-[50vh] space-y-1.5 overflow-y-auto overscroll-contain">
{documents.map((doc) => {
@@ -30,6 +30,7 @@ import {
useDeleteCoachConversationWithUndo,
} from "./use-coach";
import { QueryErrorRow } from "@/components/ui/query-error-row";
import { EmptyState } from "@/components/ui/empty-state";
/**
* The Coach's conversation list: the full history grouped by recency
@@ -169,12 +170,13 @@ export function HistoryRail({
className="px-2 py-3"
/>
) : groups.length === 0 ? (
<p
<EmptyState
variant="plain"
size="compact"
title={t("insights.coach.historyEmpty")}
className="px-2"
data-slot="coach-history-empty"
className="text-muted-foreground px-2 py-3 text-sm leading-relaxed"
>
{t("insights.coach.historyEmpty")}
</p>
/>
) : (
groups.map((group) => (
<section
@@ -32,6 +32,7 @@ import {
type IntradayResolution,
type TensionWindow,
} from "@/lib/analytics/intraday-pulse";
import { ChartEmptyState } from "@/components/charts/chart-empty-state";
/** Slim DTO the intraday route returns (type-only — no server code bundled). */
interface IntradayPulseDto {
@@ -264,9 +265,10 @@ export function IntradayPulseChart({
// A lone reading or two on a 24-hour axis drew a dot in an empty
// field and called it the course of the day. Below a handful of
// buckets the card says there is not enough for a course.
<div className="text-muted-foreground flex h-44 items-center justify-center rounded-lg border border-dashed text-sm">
{t("insights.intradayPulse.empty")}
</div>
<ChartEmptyState
title={t("insights.intradayPulse.empty")}
height={176}
/>
) : (
<div className="touch-pan-y">
<ResponsiveContainer width="100%" height={180}>
@@ -25,6 +25,7 @@ import type {
EfficacyTargetView,
} from "@/lib/medications/efficacy/build-efficacy";
import { InlineAction } from "@/components/ui/inline-action";
import { EmptyState } from "@/components/ui/empty-state";
function primaryWithDelta(
dto: MedicationEfficacyDTO,
@@ -79,9 +80,11 @@ export function MedicationEfficacySummary({
</CardHeader>
<CardContent className="space-y-3">
{rows.length === 0 ? (
<p className="text-muted-foreground text-sm">
{t("medications.efficacy.insights.empty")}
</p>
<EmptyState
variant="plain"
size="compact"
title={t("medications.efficacy.insights.empty")}
/>
) : (
<ul className="divide-border/60 divide-y">
{rows.map(({ med, target }) => {
@@ -31,6 +31,7 @@ import {
} from "@/lib/mood/dimensions";
import { cn } from "@/lib/utils";
import { Segmented } from "@/components/ui/segmented";
import { EmptyState } from "@/components/ui/empty-state";
/**
* v1.37 — the five level-A dimensions over time.
@@ -129,9 +130,11 @@ export function MoodDimensionTrends({
if (present.length === 0) {
return (
<p className="text-muted-foreground text-sm">
{t("insights.mood.dimensions.none")}
</p>
<EmptyState
variant="plain"
size="compact"
title={t("insights.mood.dimensions.none")}
/>
);
}
@@ -21,6 +21,7 @@ import {
moodPairsOf,
type CorrelationDiscoveryResponse,
} from "./mood-discovered-relations";
import { EmptyState } from "@/components/ui/empty-state";
/**
* v1.12.7 — the single "What stands out" card.
@@ -96,12 +97,12 @@ export function MoodWhatStandsOut({
/>
) : null}
{!isLoading && !isError && data && !hasDiscovered ? (
<p
<EmptyState
variant="plain"
size="compact"
title={t("insights.pattern.empty")}
data-slot="mood-discovery-empty"
className="text-muted-foreground text-sm"
>
{t("insights.pattern.empty")}
</p>
/>
) : null}
{hasDiscovered && (
<MoodDiscoveredRelations