Rename all 1,169 components to path-based names with namespace support

Component names now reflect filesystem location using / as path separator
and : as namespace separator for shared components:
  ~sx-header → ~layouts/header
  ~layout-app-body → ~shared:layout/app-body
  ~blog-admin-dashboard → ~admin/dashboard

209 files, 4,941 replacements across all services.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 22:00:12 +00:00
parent de80d921e9
commit b0920a1121
209 changed files with 4620 additions and 4620 deletions

View File

@@ -1,12 +1,12 @@
;; Cart calendar entry components
(defcomp ~cart-cal-entry (&key (name :as string) (date-str :as string) (cost :as string))
(defcomp ~calendar/cal-entry (&key (name :as string) (date-str :as string) (cost :as string))
(li :class "flex items-start justify-between text-sm"
(div (div :class "font-medium" name)
(div :class "text-xs text-stone-500" date-str))
(div :class "ml-4 font-medium" cost)))
(defcomp ~cart-cal-section (&key items)
(defcomp ~calendar/cal-section (&key items)
(div :class "mt-6 border-t border-stone-200 pt-4"
(h2 :class "text-base font-semibold mb-2" "Calendar bookings")
(ul :class "space-y-2" items)))

View File

@@ -4,6 +4,6 @@
;; Renders the "orders" link for the account dashboard nav.
(defhandler account-nav-item (&key)
(~account-nav-item
(~shared:fragments/account-nav-item
:href (app-url "cart" "/orders/")
:label "orders"))

View File

@@ -10,7 +10,7 @@
(count (+ (or (get summary "count") 0)
(or (get summary "calendar_count") 0)
(or (get summary "ticket_count") 0))))
(~cart-mini
(~shared:fragments/cart-mini
:cart-count count
:blog-url (app-url "blog" "")
:cart-url (app-url "cart" "")

View File

@@ -1,14 +1,14 @@
;; Cart header components
(defcomp ~cart-page-label-img (&key src)
(defcomp ~header/page-label-img (&key src)
(img :src src :class "h-8 w-8 rounded-full object-cover border border-stone-300 flex-shrink-0"))
(defcomp ~cart-page-label (&key feature-image title)
(defcomp ~header/page-label (&key feature-image title)
(<> (when feature-image
(~cart-page-label-img :src feature-image))
(~header/page-label-img :src feature-image))
(span title)))
(defcomp ~cart-all-carts-link (&key href)
(defcomp ~header/all-carts-link (&key href)
(a :href href :class "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-stone-300 bg-white hover:bg-stone-50 transition"
(i :class "fa fa-arrow-left text-xs" :aria-hidden "true") "All carts"))

View File

@@ -1,29 +1,29 @@
;; Cart item components
(defcomp ~cart-item-img (&key (src :as string) (alt :as string))
(defcomp ~items/img (&key (src :as string) (alt :as string))
(img :src src :alt alt :class "w-24 h-24 sm:w-32 sm:h-28 object-cover rounded-xl border border-stone-100" :loading "lazy"))
(defcomp ~cart-item-price (&key (text :as string))
(defcomp ~items/price (&key (text :as string))
(p :class "text-sm sm:text-base font-semibold text-stone-900" text))
(defcomp ~cart-item-price-was (&key (text :as string))
(defcomp ~items/price-was (&key (text :as string))
(p :class "text-xs text-stone-400 line-through" text))
(defcomp ~cart-item-no-price ()
(defcomp ~items/no-price ()
(p :class "text-xs text-stone-500" "No price"))
(defcomp ~cart-item-deleted ()
(defcomp ~items/deleted ()
(p :class "mt-2 inline-flex items-center gap-1 text-[0.65rem] sm:text-xs font-medium text-amber-700 bg-amber-50 border border-amber-200 rounded-full px-2 py-0.5"
(i :class "fa-solid fa-triangle-exclamation text-[0.6rem]" :aria-hidden "true")
" This item is no longer available or price has changed"))
(defcomp ~cart-item-brand (&key (brand :as string))
(defcomp ~items/brand (&key (brand :as string))
(p :class "mt-0.5 text-[0.7rem] sm:text-xs text-stone-500" brand))
(defcomp ~cart-item-line-total (&key (text :as string))
(defcomp ~items/line-total (&key (text :as string))
(p :class "text-sm sm:text-base font-semibold text-stone-900" text))
(defcomp ~cart-item (&key (id :as string) img (prod-url :as string) (title :as string) brand deleted price (qty-url :as string) (csrf :as string) (minus :as string) (qty :as string) (plus :as string) line-total)
(defcomp ~items/index (&key (id :as string) img (prod-url :as string) (title :as string) brand deleted price (qty-url :as string) (csrf :as string) (minus :as string) (qty :as string) (plus :as string) line-total)
(article :id id :class "flex flex-col sm:flex-row gap-3 sm:gap-4 rounded-2xl bg-white shadow-sm border border-stone-200 p-3 sm:p-4 md:p-5"
(div :class "w-full sm:w-32 shrink-0 flex justify-center sm:block" (when img img))
(div :class "flex-1 min-w-0"
@@ -47,14 +47,14 @@
(button :type "submit" :class "inline-flex items-center justify-center w-8 h-8 text-sm font-medium rounded-full border border-emerald-600 text-emerald-700 hover:bg-emerald-50 text-xl" "+")))
(div :class "flex items-center justify-between sm:justify-end gap-3" (when line-total line-total))))))
(defcomp ~cart-page-panel (&key items cal tickets summary)
(defcomp ~items/page-panel (&key items cal tickets summary)
(div :class "max-w-full px-3 py-3 space-y-3"
(div :id "cart"
(div (section :class "space-y-3 sm:space-y-4" items cal tickets)
summary))))
;; Assembled cart item from serialized data — replaces Python _cart_item_sx
(defcomp ~cart-item-from-data (&key (item :as dict))
(defcomp ~items/from-data (&key (item :as dict))
(let* ((slug (or (get item "slug") ""))
(title (or (get item "title") ""))
(image (get item "image"))
@@ -71,48 +71,48 @@
(qty-url (or (get item "qty_url") ""))
(csrf (csrf-token))
(line-total (when unit-price (* unit-price quantity))))
(~cart-item
(~items/index
:id (str "cart-item-" slug)
:img (if image
(~cart-item-img :src image :alt title)
(~img-or-placeholder :src nil
(~items/img :src image :alt title)
(~shared:misc/img-or-placeholder :src nil
:size-cls "w-24 h-24 sm:w-32 sm:h-28 rounded-xl border border-dashed border-stone-300"
:placeholder-text "No image"))
:prod-url prod-url
:title title
:brand (when brand (~cart-item-brand :brand brand))
:deleted (when is-deleted (~cart-item-deleted))
:brand (when brand (~items/brand :brand brand))
:deleted (when is-deleted (~items/deleted))
:price (if unit-price
(<>
(~cart-item-price :text (str symbol (format-decimal unit-price 2)))
(~items/price :text (str symbol (format-decimal unit-price 2)))
(when (and special-price (!= special-price regular-price))
(~cart-item-price-was :text (str symbol (format-decimal regular-price 2)))))
(~cart-item-no-price))
(~items/price-was :text (str symbol (format-decimal regular-price 2)))))
(~items/no-price))
:qty-url qty-url :csrf csrf
:minus (str (- quantity 1))
:qty (str quantity)
:plus (str (+ quantity 1))
:line-total (when line-total
(~cart-item-line-total :text (str "Line total: " symbol (format-decimal line-total 2)))))))
(~items/line-total :text (str "Line total: " symbol (format-decimal line-total 2)))))))
;; Assembled calendar entries section — replaces Python _calendar_entries_sx
(defcomp ~cart-cal-section-from-data (&key (entries :as list))
(defcomp ~items/cal-section-from-data (&key (entries :as list))
(when (not (empty? entries))
(~cart-cal-section
(~calendar/cal-section
:items (map (lambda (e)
(let* ((name (or (get e "name") ""))
(date-str (or (get e "date_str") "")))
(~cart-cal-entry
(~calendar/cal-entry
:name name :date-str date-str
:cost (str "\u00a3" (format-decimal (or (get e "cost") 0) 2)))))
entries))))
;; Assembled ticket groups section — replaces Python _ticket_groups_sx
(defcomp ~cart-tickets-section-from-data (&key (ticket-groups :as list))
(defcomp ~items/tickets-section-from-data (&key (ticket-groups :as list))
(when (not (empty? ticket-groups))
(let* ((csrf (csrf-token))
(qty-url (url-for "cart_global.update_ticket_quantity")))
(~cart-tickets-section
(~tickets/section
:items (map (lambda (tg)
(let* ((name (or (get tg "entry_name") ""))
(tt-name (get tg "ticket_type_name"))
@@ -122,14 +122,14 @@
(entry-id (str (or (get tg "entry_id") "")))
(tt-id (get tg "ticket_type_id"))
(date-str (or (get tg "date_str") "")))
(~cart-ticket-article
(~tickets/article
:name name
:type-name (when tt-name (~cart-ticket-type-name :name tt-name))
:type-name (when tt-name (~tickets/type-name :name tt-name))
:date-str date-str
:price (str "\u00a3" (format-decimal price 2))
:qty-url qty-url :csrf csrf
:entry-id entry-id
:type-hidden (when tt-id (~cart-ticket-type-hidden :value (str tt-id)))
:type-hidden (when tt-id (~tickets/type-hidden :value (str tt-id)))
:minus (str (max (- quantity 1) 0))
:qty (str quantity)
:plus (str (+ quantity 1))
@@ -137,29 +137,29 @@
ticket-groups)))))
;; Assembled cart summary — replaces Python _cart_summary_sx
(defcomp ~cart-summary-from-data (&key (item-count :as number) (grand-total :as number) (symbol :as string) (is-logged-in :as boolean) (checkout-action :as string) (login-href :as string) (user-email :as string?))
(~cart-summary-panel
(defcomp ~items/summary-from-data (&key (item-count :as number) (grand-total :as number) (symbol :as string) (is-logged-in :as boolean) (checkout-action :as string) (login-href :as string) (user-email :as string?))
(~summary/panel
:item-count (str item-count)
:subtotal (str symbol (format-decimal grand-total 2))
:checkout (if is-logged-in
(~cart-checkout-form
(~summary/checkout-form
:action checkout-action :csrf (csrf-token)
:label (str " Checkout as " user-email))
(~cart-checkout-signin :href login-href))))
(~summary/checkout-signin :href login-href))))
;; Assembled page cart content — replaces Python _page_cart_main_panel_sx
(defcomp ~cart-page-cart-content (&key (cart-items :as list?) (cal-entries :as list?) (ticket-groups :as list?) summary)
(defcomp ~items/page-cart-content (&key (cart-items :as list?) (cal-entries :as list?) (ticket-groups :as list?) summary)
(if (and (empty? (or cart-items (list)))
(empty? (or cal-entries (list)))
(empty? (or ticket-groups (list))))
(div :class "max-w-full px-3 py-3 space-y-3"
(div :id "cart"
(div :class "rounded-2xl border border-dashed border-stone-300 bg-white/80 p-6 sm:p-8 text-center"
(~empty-state :icon "fa fa-shopping-cart" :message "Your cart is empty" :cls "text-center"))))
(~cart-page-panel
:items (map (lambda (item) (~cart-item-from-data :item item)) (or cart-items (list)))
(~shared:misc/empty-state :icon "fa fa-shopping-cart" :message "Your cart is empty" :cls "text-center"))))
(~items/page-panel
:items (map (lambda (item) (~items/from-data :item item)) (or cart-items (list)))
:cal (when (not (empty? (or cal-entries (list))))
(~cart-cal-section-from-data :entries cal-entries))
(~items/cal-section-from-data :entries cal-entries))
:tickets (when (not (empty? (or ticket-groups (list))))
(~cart-tickets-section-from-data :ticket-groups ticket-groups))
(~items/tickets-section-from-data :ticket-groups ticket-groups))
:summary summary)))

View File

@@ -10,17 +10,17 @@
(quasiquote
(let ((__cpctx (cart-page-ctx)))
(<>
(~menu-row-sx :id "cart-row" :level 1 :colour "sky"
(~shared:layout/menu-row-sx :id "cart-row" :level 1 :colour "sky"
:link-href (get __cpctx "cart-url")
:link-label "cart" :icon "fa fa-shopping-cart"
:child-id "cart-header-child")
(~header-child-sx :id "cart-header-child"
:inner (~menu-row-sx :id "page-cart-row" :level 2 :colour "sky"
(~shared:layout/header-child-sx :id "cart-header-child"
:inner (~shared:layout/menu-row-sx :id "page-cart-row" :level 2 :colour "sky"
:link-href (get __cpctx "page-cart-url")
:link-label-content (~cart-page-label
:link-label-content (~header/page-label
:feature-image (get __cpctx "feature-image")
:title (get __cpctx "title"))
:nav (~cart-all-carts-link :href (get __cpctx "cart-url"))
:nav (~header/all-carts-link :href (get __cpctx "cart-url"))
:oob (unquote oob)))))))
(defmacro ~cart-page-header-oob ()
@@ -28,14 +28,14 @@
(quasiquote
(let ((__cpctx (cart-page-ctx)))
(<>
(~menu-row-sx :id "page-cart-row" :level 2 :colour "sky"
(~shared:layout/menu-row-sx :id "page-cart-row" :level 2 :colour "sky"
:link-href (get __cpctx "page-cart-url")
:link-label-content (~cart-page-label
:link-label-content (~header/page-label
:feature-image (get __cpctx "feature-image")
:title (get __cpctx "title"))
:nav (~cart-all-carts-link :href (get __cpctx "cart-url"))
:nav (~header/all-carts-link :href (get __cpctx "cart-url"))
:oob true)
(~menu-row-sx :id "cart-row" :level 1 :colour "sky"
(~shared:layout/menu-row-sx :id "cart-row" :level 1 :colour "sky"
:link-href (get __cpctx "cart-url")
:link-label "cart" :icon "fa fa-shopping-cart"
:child-id "cart-header-child"
@@ -45,12 +45,12 @@
;; cart-page layout: root + cart row + page-cart row
;; ---------------------------------------------------------------------------
(defcomp ~cart-page-layout-full ()
(defcomp ~layouts/page-layout-full ()
(<> (~root-header-auto)
(~header-child-sx
(~shared:layout/header-child-sx
:inner (~cart-page-header-auto))))
(defcomp ~cart-page-layout-oob ()
(defcomp ~layouts/page-layout-oob ()
(<> (~cart-page-header-oob)
(~root-header-auto true)))
@@ -59,14 +59,14 @@
;; Uses (post-header-ctx) — requires :data handler to populate g._defpage_ctx
;; ---------------------------------------------------------------------------
(defcomp ~cart-admin-layout-full (&key selected)
(defcomp ~layouts/admin-layout-full (&key selected)
(<> (~root-header-auto)
(~header-child-sx
(~shared:layout/header-child-sx
:inner (~post-header-auto nil))))
(defcomp ~cart-admin-layout-oob (&key selected)
(defcomp ~layouts/admin-layout-oob (&key selected)
(<> (~post-header-auto true)
(~oob-header-sx :parent-id "post-header-child"
(~shared:layout/oob-header-sx :parent-id "post-header-child"
:row (~post-admin-header-auto nil selected))
(~root-header-auto true)))
@@ -74,63 +74,63 @@
;; orders-within-cart: root + auth-simple + orders
;; ---------------------------------------------------------------------------
(defcomp ~cart-orders-layout-full (&key list-url)
(defcomp ~layouts/orders-layout-full (&key list-url)
(<> (~root-header-auto)
(~header-child-sx
(~shared:layout/header-child-sx
:inner (<> (~auth-header-row-simple-auto)
(~header-child-sx :id "auth-header-child"
:inner (~orders-header-row :list-url list-url))))))
(~shared:layout/header-child-sx :id "auth-header-child"
:inner (~shared:auth/orders-header-row :list-url list-url))))))
(defcomp ~cart-orders-layout-oob (&key list-url)
(defcomp ~layouts/orders-layout-oob (&key list-url)
(<> (~auth-header-row-simple-auto true)
(~oob-header-sx
(~shared:layout/oob-header-sx
:parent-id "auth-header-child"
:row (~orders-header-row :list-url list-url))
:row (~shared:auth/orders-header-row :list-url list-url))
(~root-header-auto true)))
;; ---------------------------------------------------------------------------
;; order-detail-within-cart: root + auth-simple + orders + order
;; ---------------------------------------------------------------------------
(defcomp ~cart-order-detail-layout-full (&key list-url detail-url order-label)
(defcomp ~layouts/order-detail-layout-full (&key list-url detail-url order-label)
(<> (~root-header-auto)
(~header-child-sx
(~shared:layout/header-child-sx
:inner (<> (~auth-header-row-simple-auto)
(~header-child-sx :id "auth-header-child"
:inner (<> (~orders-header-row :list-url list-url)
(~header-child-sx :id "orders-header-child"
:inner (~menu-row-sx :id "order-row" :level 3 :colour "sky"
(~shared:layout/header-child-sx :id "auth-header-child"
:inner (<> (~shared:auth/orders-header-row :list-url list-url)
(~shared:layout/header-child-sx :id "orders-header-child"
:inner (~shared:layout/menu-row-sx :id "order-row" :level 3 :colour "sky"
:link-href detail-url
:link-label order-label
:icon "fa fa-gbp"))))))))
(defcomp ~cart-order-detail-layout-oob (&key detail-url order-label)
(<> (~oob-header-sx
(defcomp ~layouts/order-detail-layout-oob (&key detail-url order-label)
(<> (~shared:layout/oob-header-sx
:parent-id "orders-header-child"
:row (~menu-row-sx :id "order-row" :level 3 :colour "sky"
:row (~shared:layout/menu-row-sx :id "order-row" :level 3 :colour "sky"
:link-href detail-url :link-label order-label
:icon "fa fa-gbp" :oob true))
(~root-header-auto true)))
;; --- orders rows wrapper (for infinite scroll) ---
(defcomp ~cart-orders-rows (&key rows next-scroll)
(defcomp ~layouts/orders-rows (&key rows next-scroll)
(<> rows next-scroll))
;; Composition defcomp — replaces Python loop in render_orders_rows
(defcomp ~cart-orders-rows-content (&key orders detail-url-prefix page total-pages next-url)
(~cart-orders-rows
(defcomp ~layouts/orders-rows-content (&key orders detail-url-prefix page total-pages next-url)
(~layouts/orders-rows
:rows (map (lambda (od)
(~order-row-pair :order od :detail-url-prefix detail-url-prefix))
(~shared:orders/row-pair :order od :detail-url-prefix detail-url-prefix))
(or orders (list)))
:next-scroll (if (< page total-pages)
(~infinite-scroll :url next-url :page page
(~shared:controls/infinite-scroll :url next-url :page page
:total-pages total-pages :id-prefix "orders" :colspan 5)
(~order-end-row))))
(~shared:orders/end-row))))
;; Composition defcomp — replaces conditional composition in render_checkout_error_page
(defcomp ~cart-checkout-error-from-data (&key msg order-id back-url)
(~checkout-error-content
(defcomp ~layouts/checkout-error-from-data (&key msg order-id back-url)
(~shared:orders/checkout-error-content
:msg msg
:order (when order-id (~checkout-error-order-id :oid (str "#" order-id)))
:order (when order-id (~shared:orders/checkout-error-order-id :oid (str "#" order-id)))
:back-url back-url))

View File

@@ -1,20 +1,20 @@
;; Cart overview components
(defcomp ~cart-badge (&key (icon :as string) (text :as string))
(defcomp ~overview/badge (&key (icon :as string) (text :as string))
(span :class "inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-stone-100"
(i :class icon :aria-hidden "true") text))
(defcomp ~cart-badges-wrap (&key badges)
(defcomp ~overview/badges-wrap (&key badges)
(div :class "mt-1 flex flex-wrap gap-2 text-xs text-stone-600"
badges))
(defcomp ~cart-group-card-img (&key (src :as string) (alt :as string))
(defcomp ~overview/group-card-img (&key (src :as string) (alt :as string))
(img :src src :alt alt :class "h-16 w-16 rounded-xl object-cover border border-stone-200 flex-shrink-0"))
(defcomp ~cart-mp-subtitle (&key (title :as string))
(defcomp ~overview/mp-subtitle (&key (title :as string))
(p :class "text-xs text-stone-500 truncate" title))
(defcomp ~cart-group-card (&key (href :as string) img (display-title :as string) subtitle badges (total :as string))
(defcomp ~overview/group-card (&key (href :as string) img (display-title :as string) subtitle badges (total :as string))
(a :href href :class "block rounded-2xl border border-stone-200 bg-white shadow-sm hover:shadow-md hover:border-stone-300 transition p-4 sm:p-5"
(div :class "flex items-start gap-4"
img
@@ -25,7 +25,7 @@
(div :class "text-lg font-bold text-stone-900" total)
(div :class "mt-1 text-xs text-emerald-700 font-medium" "View cart \u2192")))))
(defcomp ~cart-orphan-card (&key badges (total :as string))
(defcomp ~overview/orphan-card (&key badges (total :as string))
(div :class "rounded-2xl border border-dashed border-amber-300 bg-amber-50/60 p-4 sm:p-5"
(div :class "flex items-start gap-4"
(div :class "h-16 w-16 rounded-xl bg-amber-100 flex items-center justify-center flex-shrink-0"
@@ -36,17 +36,17 @@
(div :class "text-right flex-shrink-0"
(div :class "text-lg font-bold text-stone-900" total)))))
(defcomp ~cart-overview-panel (&key cards)
(defcomp ~overview/panel (&key cards)
(div :class "max-w-full px-3 py-3 space-y-3"
(div :class "space-y-4" cards)))
(defcomp ~cart-empty ()
(defcomp ~overview/empty ()
(div :class "max-w-full px-3 py-3 space-y-3"
(div :class "rounded-2xl border border-dashed border-stone-300 bg-white/80 p-6 sm:p-8 text-center"
(~empty-state :icon "fa fa-shopping-cart" :message "Your cart is empty" :cls "text-center"))))
(~shared:misc/empty-state :icon "fa fa-shopping-cart" :message "Your cart is empty" :cls "text-center"))))
;; Assembled page group card — replaces Python _page_group_card_sx
(defcomp ~cart-page-group-card-from-data (&key (grp :as dict) (cart-url-base :as string))
(defcomp ~overview/page-group-card-from-data (&key (grp :as dict) (cart-url-base :as string))
(let* ((post (get grp "post"))
(product-count (or (get grp "product_count") 0))
(calendar-count (or (get grp "calendar_count") 0))
@@ -55,13 +55,13 @@
(market-place (get grp "market_place"))
(badges (<>
(when (> product-count 0)
(~cart-badge :icon "fa fa-box-open"
(~overview/badge :icon "fa fa-box-open"
:text (str product-count " item" (pluralize product-count))))
(when (> calendar-count 0)
(~cart-badge :icon "fa fa-calendar"
(~overview/badge :icon "fa fa-calendar"
:text (str calendar-count " booking" (pluralize calendar-count))))
(when (> ticket-count 0)
(~cart-badge :icon "fa fa-ticket"
(~overview/badge :icon "fa fa-ticket"
:text (str ticket-count " ticket" (pluralize ticket-count)))))))
(if post
(let* ((slug (or (get post "slug") ""))
@@ -69,26 +69,26 @@
(feature-image (get post "feature_image"))
(mp-name (if market-place (or (get market-place "name") "") ""))
(display-title (if (!= mp-name "") mp-name title)))
(~cart-group-card
(~overview/group-card
:href (str cart-url-base "/" slug "/")
:img (if feature-image
(~cart-group-card-img :src feature-image :alt title)
(~img-or-placeholder :src nil :size-cls "h-16 w-16 rounded-xl"
(~overview/group-card-img :src feature-image :alt title)
(~shared:misc/img-or-placeholder :src nil :size-cls "h-16 w-16 rounded-xl"
:placeholder-icon "fa fa-store text-xl"))
:display-title display-title
:subtitle (when (!= mp-name "")
(~cart-mp-subtitle :title title))
:badges (~cart-badges-wrap :badges badges)
(~overview/mp-subtitle :title title))
:badges (~overview/badges-wrap :badges badges)
:total (str "\u00a3" (format-decimal total 2))))
(~cart-orphan-card
:badges (~cart-badges-wrap :badges badges)
(~overview/orphan-card
:badges (~overview/badges-wrap :badges badges)
:total (str "\u00a3" (format-decimal total 2))))))
;; Assembled cart overview content — replaces Python _overview_main_panel_sx
(defcomp ~cart-overview-content (&key (page-groups :as list) (cart-url-base :as string))
(defcomp ~overview/content (&key (page-groups :as list) (cart-url-base :as string))
(if (empty? page-groups)
(~cart-empty)
(~cart-overview-panel
(~overview/empty)
(~overview/panel
:cards (map (lambda (grp)
(~cart-page-group-card-from-data :grp grp :cart-url-base cart-url-base))
(~overview/page-group-card-from-data :grp grp :cart-url-base cart-url-base))
page-groups))))

View File

@@ -1,13 +1,13 @@
;; Cart payments components
(defcomp ~cart-payments-panel (&key update-url csrf merchant-code placeholder input-cls sumup-configured checkout-prefix)
(defcomp ~payments/panel (&key update-url csrf merchant-code placeholder input-cls sumup-configured checkout-prefix)
(section :class "p-4 max-w-lg mx-auto"
(~sumup-settings-form :update-url update-url :csrf csrf :merchant-code merchant-code
(~shared:misc/sumup-settings-form :update-url update-url :csrf csrf :merchant-code merchant-code
:placeholder placeholder :input-cls input-cls :sumup-configured sumup-configured
:checkout-prefix checkout-prefix :sx-select "#payments-panel")))
;; Assembled cart admin overview content
(defcomp ~cart-admin-content ()
(defcomp ~payments/admin-content ()
(let* ((payments-href (url-for "defpage_cart_payments")))
(div :id "main-panel"
(div :class "flex items-center justify-between p-3 border-b"
@@ -15,13 +15,13 @@
(a :href payments-href :class "text-sm underline" "configure")))))
;; Assembled cart payments content
(defcomp ~cart-payments-content (&key page-config)
(defcomp ~payments/content (&key page-config)
(let* ((sumup-configured (and page-config (get page-config "sumup_api_key")))
(merchant-code (or (get page-config "sumup_merchant_code") ""))
(checkout-prefix (or (get page-config "sumup_checkout_prefix") ""))
(placeholder (if sumup-configured "--------" "sup_sk_..."))
(input-cls "w-full px-3 py-1.5 text-sm border border-stone-300 rounded focus:ring-purple-500 focus:border-purple-500"))
(~cart-payments-panel
(~payments/panel
:update-url (url-for "page_admin.update_sumup")
:csrf (csrf-token)
:merchant-code merchant-code

View File

@@ -1,17 +1,17 @@
;; Cart summary / checkout components
(defcomp ~cart-checkout-form (&key (action :as string) (csrf :as string) (label :as string))
(defcomp ~summary/checkout-form (&key (action :as string) (csrf :as string) (label :as string))
(form :method "post" :action action :class "w-full"
(input :type "hidden" :name "csrf_token" :value csrf)
(button :type "submit" :class "w-full inline-flex items-center justify-center px-4 py-2 text-xs sm:text-sm rounded-full border border-emerald-600 bg-emerald-600 text-white hover:bg-emerald-700 transition"
(i :class "fa-solid fa-credit-card mr-2" :aria-hidden "true") label)))
(defcomp ~cart-checkout-signin (&key (href :as string))
(defcomp ~summary/checkout-signin (&key (href :as string))
(div :class "w-full flex"
(a :href href :class "w-full cursor-pointer flex flex-row items-center justify-center p-3 gap-2 rounded bg-stone-200 text-black hover:bg-stone-300 transition"
(i :class "fa-solid fa-key") (span "sign in or register to checkout"))))
(defcomp ~cart-summary-panel (&key (item-count :as string) (subtotal :as string) checkout)
(defcomp ~summary/panel (&key (item-count :as string) (subtotal :as string) checkout)
(aside :id "cart-summary" :class "lg:pl-2"
(div :class "rounded-2xl bg-white shadow-sm border border-stone-200 p-4 sm:p-5"
(h2 :class "text-sm sm:text-base font-semibold text-stone-900 mb-3 sm:mb-4" "Order summary")

View File

@@ -1,12 +1,12 @@
;; Cart ticket components
(defcomp ~cart-ticket-type-name (&key (name :as string))
(defcomp ~tickets/type-name (&key (name :as string))
(p :class "mt-0.5 text-[0.7rem] sm:text-xs text-stone-500" name))
(defcomp ~cart-ticket-type-hidden (&key (value :as string))
(defcomp ~tickets/type-hidden (&key (value :as string))
(input :type "hidden" :name "ticket_type_id" :value value))
(defcomp ~cart-ticket-article (&key (name :as string) type-name (date-str :as string) (price :as string) (qty-url :as string) (csrf :as string) (entry-id :as string) type-hidden (minus :as string) (qty :as string) (plus :as string) (line-total :as string))
(defcomp ~tickets/article (&key (name :as string) type-name (date-str :as string) (price :as string) (qty-url :as string) (csrf :as string) (entry-id :as string) type-hidden (minus :as string) (qty :as string) (plus :as string) (line-total :as string))
(article :class "flex flex-col sm:flex-row gap-3 sm:gap-4 rounded-2xl bg-white shadow-sm border border-stone-200 p-3 sm:p-4"
(div :class "flex-1 min-w-0"
(div :class "flex flex-col sm:flex-row sm:items-start justify-between gap-2 sm:gap-3"
@@ -35,7 +35,7 @@
(div :class "flex items-center justify-between sm:justify-end gap-3"
(p :class "text-sm sm:text-base font-semibold text-stone-900" line-total))))))
(defcomp ~cart-tickets-section (&key items)
(defcomp ~tickets/section (&key items)
(div :class "mt-6 border-t border-stone-200 pt-4"
(h2 :class "text-base font-semibold mb-2"
(i :class "fa fa-ticket mr-1" :aria-hidden "true") " Event tickets")

View File

@@ -6,7 +6,7 @@
:auth :public
:layout :root
:data (service "cart-page" "overview-data")
:content (~cart-overview-content
:content (~overview/content
:page-groups page-groups
:cart-url-base cart-url-base))
@@ -15,11 +15,11 @@
:auth :public
:layout :cart-page
:data (service "cart-page" "page-cart-data")
:content (~cart-page-cart-content
:content (~items/page-cart-content
:cart-items cart-items
:cal-entries cal-entries
:ticket-groups ticket-groups
:summary (~cart-summary-from-data
:summary (~items/summary-from-data
:item-count (get summary "item_count")
:grand-total (get summary "grand_total")
:symbol (get summary "symbol")
@@ -33,12 +33,12 @@
:auth :admin
:layout :cart-admin
:data (service "cart-page" "admin-data")
:content (~cart-admin-content))
:content (~payments/admin-content))
(defpage cart-payments
:path "/<page_slug>/admin/payments/"
:auth :admin
:layout (:cart-admin :selected "payments")
:data (service "cart-page" "payments-admin-data")
:content (~cart-payments-content
:content (~payments/content
:page-config page-config))