merge(sleep): side-by-side sleep-debt and rhythm cards when both present

This commit is contained in:
Marc-André Bombeck committed 2026-06-14 23:03:06 +02:00
commit 2d1c02ce7b
2 files changed
+51 -1

No files matched your search

@@ -102,6 +102,41 @@ describe("<SleepRhythmSection>", () => {
expect(html).toContain("md:py-6");
});
it("places the two cards side by side when both carry settled data", () => {
rhythmMock.mockReturnValue({
data: READY_DTO,
isLoading: false,
isError: false,
});
const html = render(<SleepRhythmSection enabled />);
// Two-up on large screens, single column below.
expect(html).toContain("lg:grid-cols-2");
});
it("keeps a lone data-bearing card full width when the other is still learning", () => {
rhythmMock.mockReturnValue({
data: {
...READY_DTO,
// Sleep-debt settled, chronotype still learning → no two-up grid.
chronotype: {
state: "learning",
msfMinutes: null,
msfScMinutes: null,
band: null,
socialJetlagMinutes: null,
freeNightsCounted: 2,
workNightsCounted: 5,
freeNightsUntilReady: 4,
},
} satisfies SleepRhythmDto,
isLoading: false,
isError: false,
});
const html = render(<SleepRhythmSection enabled />);
expect(html).toContain("grid-cols-1");
expect(html).not.toContain("lg:grid-cols-2");
});
it("renders nothing when disabled", () => {
rhythmMock.mockReturnValue({
data: undefined,
@@ -2,6 +2,7 @@
import { useAuth } from "@/hooks/use-auth";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import { useTranslations } from "@/lib/i18n/context";
import { useSleepRhythm } from "./use-sleep-rhythm";
import { SleepDebtCard } from "./sleep-debt-card";
@@ -52,8 +53,22 @@ export function SleepRhythmSection({ enabled }: { enabled: boolean }) {
);
}
// Both cards are compact; when each carries a settled (non-learning) readout
// they sit two-up. A lone card with data spans full width so it never leaves
// a half-width orphan with dead space beside it (mirrors the mood Einordnung
// tiles). The cards' own learning/partial states stay stacked full-width.
const debtHasData = data.sleepDebt.state === "ready";
const chronotypeHasData =
data.chronotype.state === "ready" && data.chronotype.band != null;
const bothHaveData = debtHasData && chronotypeHasData;
return (
<div className="space-y-4">
<div
className={cn(
"grid gap-4",
bothHaveData ? "lg:grid-cols-2 lg:items-start" : "grid-cols-1",
)}
>
<SleepDebtCard debt={data.sleepDebt} />
<ChronotypeCard chronotype={data.chronotype} />
</div>