From 7b7d36dc7491723ca32d2c117819bda0c58711a2 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Wed, 2 Sep 2026 22:59:04 +0200 Subject: [PATCH] fix(views): segmented switches on the year and summary views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the two-loose-buttons pattern with Segmented on both, so spend/balance and by-post/by-month read as two states of one control rather than a filled primary action beside an unrelated outline button. Summary also had two row-height defects: "All time" was `sm` in an `items-end` row of default-height fields, so it sat 4px off their baseline; and the by-month branch's first cell was `py-2` where every other cell in the table is `py-2.5`, making those rows 4px shorter than the by-post ones. The rest of the diff is indentation — both Sections had their children at the parent's own indent level. Co-Authored-By: Claude Opus 5 (1M context) --- src/ui/routes/SummaryRoute.tsx | 145 ++++++++++++++++----------------- src/ui/routes/YearRoute.tsx | 27 +++--- 2 files changed, 83 insertions(+), 89 deletions(-) diff --git a/src/ui/routes/SummaryRoute.tsx b/src/ui/routes/SummaryRoute.tsx index 4f0ee44..8a2be02 100644 --- a/src/ui/routes/SummaryRoute.tsx +++ b/src/ui/routes/SummaryRoute.tsx @@ -7,6 +7,7 @@ import { useDataset } from "../hooks/useDataset.ts"; import { datasetMonthSpan, summaryView } from "../../domain/views.ts"; import { formatAmount, formatMoney } from "../format.ts"; import { Section, Stat } from "../components/Section.tsx"; +import { Segmented } from "../components/Segmented.tsx"; export function SummaryRoute() { const dataset = useDataset(); @@ -24,91 +25,87 @@ export function SummaryRoute() {

Summary

-
-
- - setFrom(e.target.value)} /> +
+
+ + setFrom(e.target.value)} /> +
+
+ + setTo(e.target.value)} /> +
+
-
- - setTo(e.target.value)} /> -
- -
-
+
{formatMoney(view.totalIncome, base)} {formatMoney(view.totalCharges, base)} - - {formatMoney(difference, base)} - -
+ + {formatMoney(difference, base)} + +
- {(["post", "month"] as const).map((option) => ( - - ))} - + } > - - - - - - - - - - {groupBy === "post" - ? view.byPost.map((entry) => ( - - - - - - )) - : view.byMonth.map((entry) => ( - - - - - - ))} - -
{groupBy === "post" ? "Post" : "Month"}SpentShare
{entry.post.name}{formatAmount(entry.charges)} - {view.totalCharges === 0 - ? "—" - : `${((entry.charges / view.totalCharges) * 100).toFixed(1)}%`} -
- - {entry.monthId} - - {formatAmount(entry.charges)} - {view.totalCharges === 0 - ? "—" - : `${((entry.charges / view.totalCharges) * 100).toFixed(1)}%`} -
+ + + + + + + + + + {groupBy === "post" + ? view.byPost.map((entry) => ( + + + + + + )) + : view.byMonth.map((entry) => ( + + + + + + ))} + +
{groupBy === "post" ? "Post" : "Month"}SpentShare
{entry.post.name}{formatAmount(entry.charges)} + {view.totalCharges === 0 + ? "—" + : `${((entry.charges / view.totalCharges) * 100).toFixed(1)}%`} +
+ + {entry.monthId} + + {formatAmount(entry.charges)} + {view.totalCharges === 0 + ? "—" + : `${((entry.charges / view.totalCharges) * 100).toFixed(1)}%`} +
); diff --git a/src/ui/routes/YearRoute.tsx b/src/ui/routes/YearRoute.tsx index 9b8cdb1..54ae246 100644 --- a/src/ui/routes/YearRoute.tsx +++ b/src/ui/routes/YearRoute.tsx @@ -1,10 +1,10 @@ import { useState } from "react"; import { Link, useParams } from "react-router"; -import { Button } from "@/components/ui/button"; import { useDataset } from "../hooks/useDataset.ts"; import { yearView } from "../../domain/views.ts"; import { formatMoney } from "../format.ts"; import { YearMatrix } from "../components/YearMatrix.tsx"; +import { Segmented } from "../components/Segmented.tsx"; import { Section, Stat } from "../components/Section.tsx"; export function YearRoute() { @@ -20,14 +20,14 @@ export function YearRoute() {
← {numericYear - 1}

{year}

{numericYear + 1} → @@ -43,18 +43,15 @@ export function YearRoute() {
- {(["spend", "balance"] as const).map((option) => ( - - ))} - + } >