Move rendering logic from Python for-loops building sx_call strings into SX defcomp components that use map/lambda over data dicts. Python now serializes display data into plain dicts and passes them via a single sx_call; the SX layer handles iteration and conditional rendering. Covers orders (rows, items, calendar, tickets), federation (timeline, search, actors, profile activities), and blog (cards, pages, filters, snippets, menu items, tag groups, page search, nav OOB). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
69 lines
2.6 KiB
Plaintext
69 lines
2.6 KiB
Plaintext
;; Profile and actor timeline components
|
|
|
|
(defcomp ~federation-actor-profile-header (&key avatar display-name username domain summary follow)
|
|
(div :class "bg-white rounded-lg shadow-sm border border-stone-200 p-6 mb-6"
|
|
(div :class "flex items-center gap-4"
|
|
avatar
|
|
(div :class "flex-1"
|
|
(h1 :class "text-xl font-bold" display-name)
|
|
(div :class "text-stone-500" "@" username "@" domain)
|
|
summary)
|
|
follow)))
|
|
|
|
(defcomp ~federation-actor-timeline-layout (&key header timeline)
|
|
header
|
|
(div :id "timeline" timeline))
|
|
|
|
(defcomp ~federation-follow-form (&key action csrf actor-url label cls)
|
|
(div :class "flex-shrink-0"
|
|
(form :method "post" :action action
|
|
(input :type "hidden" :name "csrf_token" :value csrf)
|
|
(input :type "hidden" :name "actor_url" :value actor-url)
|
|
(button :type "submit" :class cls label))))
|
|
|
|
(defcomp ~federation-profile-summary (&key summary)
|
|
(div :class "text-sm text-stone-600 mt-2" (~rich-text :html summary)))
|
|
|
|
;; Public profile page
|
|
|
|
(defcomp ~federation-activity-obj-type (&key obj-type)
|
|
(span :class "text-sm text-stone-500" obj-type))
|
|
|
|
(defcomp ~federation-activity-card (&key activity-type published obj-type)
|
|
(div :class "bg-white rounded-lg shadow p-4"
|
|
(div :class "flex justify-between items-start"
|
|
(span :class "font-medium" activity-type)
|
|
(span :class "text-sm text-stone-400" published))
|
|
obj-type))
|
|
|
|
(defcomp ~federation-activities-list (&key items)
|
|
(div :class "space-y-4" items))
|
|
|
|
(defcomp ~federation-activities-empty ()
|
|
(p :class "text-stone-500" "No activities yet."))
|
|
|
|
(defcomp ~federation-profile-page (&key display-name username domain summary activities-heading activities)
|
|
(div :class "py-8"
|
|
(div :class "bg-white rounded-lg shadow p-6 mb-6"
|
|
(h1 :class "text-2xl font-bold" display-name)
|
|
(p :class "text-stone-500" "@" username "@" domain)
|
|
summary)
|
|
(h2 :class "text-xl font-bold mb-4" activities-heading)
|
|
activities))
|
|
|
|
(defcomp ~federation-profile-summary-text (&key text)
|
|
(p :class "mt-2" text))
|
|
|
|
;; Data-driven activities list (replaces Python loop in render_profile_page)
|
|
(defcomp ~federation-activities-from-data (&key activities)
|
|
(if (empty? (or activities (list)))
|
|
(~federation-activities-empty)
|
|
(~federation-activities-list
|
|
:items (<> (map (lambda (a)
|
|
(~federation-activity-card
|
|
:activity-type (get a "activity_type")
|
|
:published (get a "published")
|
|
:obj-type (when (get a "object_type")
|
|
(~federation-activity-obj-type :obj-type (get a "object_type")))))
|
|
activities)))))
|