From 441f3ac06fee214d1a5c81901a051bf2202eddd7 Mon Sep 17 00:00:00 2001 From: Ricardo Canales Date: Tue, 23 Jun 2026 20:23:03 -0700 Subject: [PATCH 1/2] fix(ui): rebuild counterparty + series forms/detail in the page-form vocabulary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new /counterparties and /recurring create forms — and the counterparty detail enrichment panel — were built with the settings two-column SettingsSection/SettingsRow vocabulary, which is reserved for /settings/* tabs. On these full-page surfaces it rendered as a near-empty left gutter with the form crushed into a narrow right card, the inline label+caption column so tight that captions wrapped one word per line, and a stack of hairline SettingsRow dividers reading as stray horizontal rules. Rebuild all three in the standard page-form vocabulary used by the category/tag forms: a single bb-card with stacked label-over-input fields (bb-form-input / bb-form-select), helper text beneath each field, and a bb-action-row footer. No gutter, no dividers. The counterparty enrichment pairs Name + Category on one responsive row and stacks MCC/Website/Logo full-width. Matches the already-correct series detail page, so the two detail pages now read as siblings. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_012fRHZ1CTjEZ1xFwQmW27jU --- .../components/pages/counterparties.templ | 116 ++++++++++-------- .../components/pages/recurring_form.templ | 72 ++++++----- 2 files changed, 106 insertions(+), 82 deletions(-) diff --git a/internal/templates/components/pages/counterparties.templ b/internal/templates/components/pages/counterparties.templ index b17055b1..e3642de6 100644 --- a/internal/templates/components/pages/counterparties.templ +++ b/internal/templates/components/pages/counterparties.templ @@ -129,36 +129,49 @@ templ CounterpartyDetail(p CounterpartyDetailProps) { }) - +
@entityPanelHeader("sparkles", "Enrichment", "Name, category, and brand details", nil) -
+ - @components.SettingsSection(components.SettingsSectionProps{ - Icon: "store", - Title: "Details", - }) { - @components.SettingsRow(components.SettingsRowProps{Label: "Name", Caption: "Display label for this counterparty"}) { - - } - @components.SettingsRow(components.SettingsRowProps{Label: "Category", Caption: "Default category for its charges"}) { - - } - @components.SettingsRow(components.SettingsRowProps{Label: "MCC", Caption: "Merchant category code (4 digits)"}) { - - } - @components.SettingsRow(components.SettingsRowProps{Label: "Website", Caption: "Its domain auto-fetches a brand logo via logo.dev when counterparty logos are enabled and a logo.dev token is set in Settings", Stack: true}) { - - } - @components.SettingsRow(components.SettingsRowProps{Label: "Logo URL", Caption: "Overrides the auto-fetched logo. Hotlinked on counterparty rows.", Stack: true}) { - - } - } +
+
+
+ + +

Display label for this counterparty.

+
+
+ + +

Default category for its charges.

+
+
+
+ + +

Merchant category code (4 digits).

+
+
+ + +

Its domain auto-fetches a brand logo via logo.dev when counterparty logos are enabled and a token is set in Settings.

+
+
+ + +

Overrides the auto-fetched logo. Hotlinked on counterparty rows.

+
+
-
-
+
+ Cancel + +
+ +
} // counterpartyHeaderIcon renders the EntityHeader leading tile content — the same diff --git a/internal/templates/components/pages/recurring_form.templ b/internal/templates/components/pages/recurring_form.templ index 5c7e22d7..b4adfa7c 100644 --- a/internal/templates/components/pages/recurring_form.templ +++ b/internal/templates/components/pages/recurring_form.templ @@ -4,8 +4,10 @@ import "breadbox/internal/templates/components" // RecurringSeriesForm renders /recurring/new — a from-scratch create form for a // recurring series. A thin series needs only a name and a type; its membership -// comes from the rules you point at it afterwards. Composed from the settings -// vocabulary (SettingsSection / SettingsRow) for consistency. Plain POST form +// comes from the rules you point at it afterwards. Built in the standard +// page-form vocabulary (a single bb-card with stacked label-over-input fields + +// a bb-action-row footer), matching the category/tag create forms — NOT the +// settings two-column gutter, which is reserved for /settings/*. Plain POST form // (no Alpine) → CreateRecurringSeriesHandler mints the series and redirects to // its detail page. templ RecurringSeriesForm(p RecurringSeriesFormProps) { @@ -14,35 +16,41 @@ templ RecurringSeriesForm(p RecurringSeriesFormProps) { Subtitle: "Name a recurring series, then author rules that assign charges to it. The series starts empty.", SubtitleHideOnMobile: true, }) -
- - if p.Error != "" { -