;; Events admin components (defcomp ~events-calendar-admin-panel (&key description-content csrf description) (section :class "max-w-3xl mx-auto p-4 space-y-10" (div (h2 :class "text-xl font-semibold" "Calendar configuration") (div :id "cal-put-errors" :class "mt-2 text-sm text-red-600") (div (label :class "block text-sm font-medium text-stone-700" "Description") (when description-content description-content)) (form :id "calendar-form" :method "post" :sx-target "#main-panel" :sx-select "#main-panel" :sx-on:beforeRequest "document.querySelector('#cal-put-errors').textContent='';" :sx-on:responseError "document.querySelector('#cal-put-errors').textContent='Error'; if(event.detail.response){event.detail.response.clone().text().then(function(t){event.target.closest('form').querySelector('[id$=errors]').innerHTML=t})}" :sx-on:afterRequest "if (event.detail.successful) this.reset()" :class "hidden space-y-4 mt-4" :autocomplete "off" (input :type "hidden" :name "csrf_token" :value csrf) (div (label :class "block text-sm font-medium text-stone-700" "Description") (div description) (textarea :name "description" :autocomplete "off" :rows "4" :class "w-full p-2 border rounded" description)) (div (button :class "px-3 py-2 rounded bg-stone-800 text-white" "Save")))) (hr :class "border-stone-200"))) (defcomp ~events-entry-admin-link (&key href) (a :href href :class "inline-flex items-center gap-1 px-2 py-1 text-xs text-stone-500 hover:text-stone-700 hover:bg-stone-100 rounded" (i :class "fa fa-cog" :aria-hidden "true") " Admin")) (defcomp ~events-entry-field (&key label content) (div :class "flex flex-col mb-4" (div :class "text-xs font-semibold uppercase tracking-wide text-stone-500" label) content)) (defcomp ~events-entry-name-field (&key name) (div :class "mt-1 text-lg font-medium" name)) (defcomp ~events-entry-slot-assigned (&key slot-name flex-label) (div :class "mt-1" (span :class "px-2 py-1 rounded text-sm bg-blue-100 text-blue-700" slot-name) (span :class "ml-2 text-xs text-stone-500" flex-label))) (defcomp ~events-entry-slot-none () (div :class "mt-1" (span :class "text-sm text-stone-400" "No slot assigned"))) (defcomp ~events-entry-time-field (&key time-str) (div :class "mt-1" time-str)) (defcomp ~events-entry-state-field (&key entry-id badge) (div :class "mt-1" (div :id (str "entry-state-" entry-id) badge))) (defcomp ~events-entry-cost-field (&key cost) (div :class "mt-1" (span :class "font-medium text-green-600" cost))) (defcomp ~events-entry-tickets-field (&key entry-id tickets-config) (div :class "mt-1" :id (str "entry-tickets-" entry-id) tickets-config)) (defcomp ~events-entry-date-field (&key date-str) (div :class "mt-1" date-str)) (defcomp ~events-entry-posts-field (&key entry-id posts-panel) (div :class "mt-1" :id (str "entry-posts-" entry-id) posts-panel)) (defcomp ~events-entry-panel (&key entry-id list-container name slot time state cost tickets buy date posts options pre-action edit-url) (section :id (str "entry-" entry-id) :class list-container name slot time state cost tickets buy date posts (div :class "flex gap-2 mt-6" options (button :type "button" :class pre-action :sx-get edit-url :sx-target (str "#entry-" entry-id) :sx-swap "outerHTML" "Edit")))) (defcomp ~events-entry-title (&key name badge) (<> (i :class "fa fa-clock") " " name " " badge)) (defcomp ~events-entry-times (&key time-str) (div :class "text-sm text-gray-600" time-str)) (defcomp ~events-entry-optioned-oob (&key entry-id title state) (<> (div :id (str "entry-title-" entry-id) :sx-swap-oob "innerHTML" title) (div :id (str "entry-state-" entry-id) :sx-swap-oob "innerHTML" state))) (defcomp ~events-entry-options (&key entry-id buttons) (div :id (str "calendar_entry_options_" entry-id) :class "flex flex-col md:flex-row gap-1" buttons)) (defcomp ~events-entry-option-button (&key url target csrf btn-type action-btn confirm-title confirm-text label is-btn) (form :sx-post url :sx-select target :sx-target target :sx-swap "outerHTML" :sx-trigger (if is-btn "confirmed" nil) (input :type "hidden" :name "csrf_token" :value csrf) (button :type btn-type :class action-btn :data-confirm "true" :data-confirm-title confirm-title :data-confirm-text confirm-text :data-confirm-icon "question" :data-confirm-confirm-text (str "Yes, " label " it") :data-confirm-cancel-text "Cancel" :data-confirm-event (if is-btn "confirmed" nil) (i :class "fa-solid fa-rotate mr-2" :aria-hidden "true") label)))