;; Events entry card components (all events / page summary) (defcomp ~events-state-badge (&key cls label) (span :class (str "inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium " cls) label)) (defcomp ~events-entry-title-linked (&key href name) (a :href href :class "hover:text-emerald-700" (h2 :class "text-lg font-semibold text-stone-900" name))) (defcomp ~events-entry-title-plain (&key name) (h2 :class "text-lg font-semibold text-stone-900" name)) (defcomp ~events-entry-title-tile-linked (&key href name) (a :href href :class "hover:text-emerald-700" (h2 :class "text-base font-semibold text-stone-900 line-clamp-2" name))) (defcomp ~events-entry-title-tile-plain (&key name) (h2 :class "text-base font-semibold text-stone-900 line-clamp-2" name)) (defcomp ~events-entry-page-badge (&key href title) (a :href href :class "inline-block px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800 hover:bg-amber-200" title)) (defcomp ~events-entry-cal-badge (&key name) (span :class "inline-block px-2 py-0.5 rounded-full text-xs font-medium bg-sky-100 text-sky-700" name)) (defcomp ~events-entry-time-linked (&key href date-str) (<> (a :href href :class "hover:text-stone-700" date-str) (raw! " · "))) (defcomp ~events-entry-time-plain (&key date-str) (<> (span date-str) (raw! " · "))) (defcomp ~events-entry-cost (&key cost-html) (div :class "mt-1 text-sm font-medium text-green-600" (raw! cost-html))) (defcomp ~events-entry-card (&key title-html badges-html time-parts cost-html widget-html) (article :class "rounded-xl bg-white shadow-sm border border-stone-200 p-4" (div :class "flex flex-col sm:flex-row sm:items-start justify-between gap-3" (div :class "flex-1 min-w-0" (raw! title-html) (div :class "flex flex-wrap items-center gap-1.5 mt-1" (raw! badges-html)) (div :class "mt-1 text-sm text-stone-500" (raw! time-parts)) (raw! cost-html)) (raw! widget-html)))) (defcomp ~events-entry-card-tile (&key title-html badges-html time-html cost-html widget-html) (article :class "rounded-xl bg-white shadow-sm border border-stone-200 overflow-hidden" (div :class "p-3" (raw! title-html) (div :class "flex flex-wrap items-center gap-1 mt-1" (raw! badges-html)) (div :class "mt-1 text-xs text-stone-500" (raw! time-html)) (raw! cost-html)) (raw! widget-html))) (defcomp ~events-entry-tile-widget-wrapper (&key widget-html) (div :class "border-t border-stone-100 px-3 py-2" (raw! widget-html))) (defcomp ~events-entry-widget-wrapper (&key widget-html) (div :class "shrink-0" (raw! widget-html))) (defcomp ~events-date-separator (&key date-str) (div :class "pt-2 pb-1" (h3 :class "text-sm font-semibold text-stone-500 uppercase tracking-wide" date-str))) (defcomp ~events-sentinel (&key page next-url) (div :id (str "sentinel-" page) :class "h-4 opacity-0 pointer-events-none" :hx-get next-url :hx-trigger "intersect once delay:250ms" :hx-swap "outerHTML" :role "status" :aria-hidden "true" (div :class "text-center text-xs text-stone-400" "loading..."))) (defcomp ~events-list-svg () (svg :xmlns "http://www.w3.org/2000/svg" :class "h-5 w-5" :fill "none" :viewBox "0 0 24 24" :stroke "currentColor" :stroke-width "2" (path :stroke-linecap "round" :stroke-linejoin "round" :d "M4 6h16M4 12h16M4 18h16"))) (defcomp ~events-tile-svg () (svg :xmlns "http://www.w3.org/2000/svg" :class "h-5 w-5" :fill "none" :viewBox "0 0 24 24" :stroke "currentColor" :stroke-width "2" (path :stroke-linecap "round" :stroke-linejoin "round" :d "M4 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM14 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V5zM4 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1v-4zM14 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"))) (defcomp ~events-view-toggle (&key list-href tile-href hx-select list-active tile-active list-svg tile-svg) (div :class "hidden md:flex justify-end px-3 pt-3 gap-1" (a :href list-href :hx-get list-href :hx-target "#main-panel" :hx-select hx-select :hx-swap "outerHTML" :hx-push-url "true" :class (str "p-1.5 rounded " list-active) :title "List view" :_ "on click js localStorage.removeItem('events_view') end" (raw! list-svg)) (a :href tile-href :hx-get tile-href :hx-target "#main-panel" :hx-select hx-select :hx-swap "outerHTML" :hx-push-url "true" :class (str "p-1.5 rounded " tile-active) :title "Tile view" :_ "on click js localStorage.setItem('events_view','tile') end" (raw! tile-svg)))) (defcomp ~events-grid (&key grid-cls cards-html) (div :class grid-cls (raw! cards-html))) (defcomp ~events-empty () (div :class "px-3 py-12 text-center text-stone-400" (i :class "fa fa-calendar-xmark text-4xl mb-3" :aria-hidden "true") (p :class "text-lg" "No upcoming events"))) (defcomp ~events-main-panel-body (&key toggle-html body-html) (<> (raw! toggle-html) (raw! body-html) (div :class "pb-8")))