Files
mono/account/sx/dashboard.sx
giles 193578ef88 Move SX construction from Python to .sx defcomps (phases 0-4)
Eliminate Python s-expression string building across account, orders,
federation, and cart services. Visual rendering logic now lives entirely
in .sx defcomp components; Python files contain only data serialization,
header/layout wiring, and thin wrappers that call defcomps.

Phase 0: Shared DRY extraction — auth/orders header defcomps, format-decimal/
pluralize/escape/route-prefix primitives.
Phase 1: Account — dashboard, newsletters, login/device/check-email content.
Phase 2: Orders — order list, detail, filter, checkout return assembled defcomps.
Phase 3: Federation — social nav, post cards, timeline, search, actors,
notifications, compose, profile assembled defcomps.
Phase 4: Cart — overview, page cart items/calendar/tickets/summary, admin,
payments assembled defcomps; orders rendering reuses Phase 2 shared defcomps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:36:34 +00:00

61 lines
2.4 KiB
Plaintext

;; Account dashboard components
(defcomp ~account-error-banner (&key error)
(when error
(div :class "rounded-lg border border-red-200 bg-red-50 text-red-800 px-4 py-3 text-sm"
error)))
(defcomp ~account-user-email (&key email)
(when email
(p :class "text-sm text-stone-500 mt-1" email)))
(defcomp ~account-user-name (&key name)
(when name
(p :class "text-sm text-stone-600" name)))
(defcomp ~account-logout-form (&key csrf-token)
(form :action "/auth/logout/" :method "post"
(input :type "hidden" :name "csrf_token" :value csrf-token)
(button :type "submit"
:class "inline-flex items-center gap-2 rounded-full border border-stone-300 px-4 py-2 text-sm font-medium text-stone-700 hover:bg-stone-50 transition"
(i :class "fa-solid fa-right-from-bracket text-xs") " Sign out")))
(defcomp ~account-label-item (&key name)
(span :class "inline-flex items-center rounded-full border border-stone-200 px-3 py-1 text-xs font-medium bg-white/60"
name))
(defcomp ~account-labels-section (&key items)
(when items
(div
(h2 :class "text-base font-semibold tracking-tight mb-3" "Labels")
(div :class "flex flex-wrap gap-2" items))))
(defcomp ~account-main-panel (&key error email name logout labels)
(div :class "w-full max-w-3xl mx-auto px-4 py-6"
(div :class "bg-white/70 backdrop-blur rounded-2xl shadow border border-stone-200 p-6 sm:p-8 space-y-8"
error
(div :class "flex items-center justify-between"
(div
(h1 :class "text-xl font-semibold tracking-tight" "Account")
email
name)
logout)
labels)))
;; Assembled dashboard content — replaces Python _account_main_panel_sx
(defcomp ~account-dashboard-content (&key error)
(let* ((user (current-user))
(csrf (csrf-token)))
(~account-main-panel
:error (when error (~account-error-banner :error error))
:email (when (get user "email")
(~account-user-email :email (get user "email")))
:name (when (get user "name")
(~account-user-name :name (get user "name")))
:logout (~account-logout-form :csrf-token csrf)
:labels (when (not (empty? (or (get user "labels") (list))))
(~account-labels-section
:items (map (lambda (label)
(~account-label-item :name (get label "name")))
(get user "labels")))))))