;; Events calendar components (defcomp ~events-calendar-nav-arrow (&key pill-cls href label) (a :class (str pill-cls " text-xl") :href href :sx-get href :sx-target "#main-panel" :sx-select "#main-panel" :sx-swap "outerHTML" :sx-push-url "true" label)) (defcomp ~events-calendar-month-label (&key month-name year) (div :class "px-3 font-medium" (str month-name " " year))) (defcomp ~events-calendar-weekday (&key name) (div :class "py-1" name)) (defcomp ~events-calendar-day-short (&key day-str) (span :class "sm:hidden text-[16px] text-stone-500" day-str)) (defcomp ~events-calendar-day-num (&key pill-cls href num) (a :class pill-cls :href href :sx-get href :sx-target "#main-panel" :sx-select "#main-panel" :sx-swap "outerHTML" :sx-push-url "true" num)) (defcomp ~events-calendar-entry-badge (&key bg-cls name state-label) (div :class (str "flex items-center justify-between gap-1 text-[11px] rounded px-1 py-0.5 " bg-cls) (span :class "truncate" name) (span :class "shrink-0 text-[10px] font-semibold uppercase tracking-tight" state-label))) (defcomp ~events-calendar-cell (&key cell-cls day-short day-num badges) (div :class cell-cls (div :class "flex justify-between items-center" (div :class "flex flex-col" day-short day-num)) (div :class "mt-1 space-y-0.5" badges))) (defcomp ~events-calendar-grid (&key arrows weekdays cells) (section :class "bg-orange-100" (header :class "flex items-center justify-center mt-2" (nav :class "flex items-center gap-2 text-2xl" arrows)) (div :class "rounded-2xl border border-stone-200 bg-white/80 p-4" (div :class "hidden sm:grid grid-cols-7 text-center text-md font-semibold text-stone-700 mb-2" weekdays) (div :class "grid grid-cols-1 sm:grid-cols-7 gap-px bg-stone-200 rounded-xl overflow-hidden" cells)))) (defcomp ~events-calendars-create-form (&key create-url csrf) (<> (div :id "cal-create-errors" :class "mt-2 text-sm text-red-600") (form :class "mt-4 flex gap-2 items-end" :sx-post create-url :sx-target "#calendars-list" :sx-select "#calendars-list" :sx-swap "outerHTML" :sx-on:beforeRequest "document.querySelector('#cal-create-errors').textContent='';" :sx-on:responseError "document.querySelector('#cal-create-errors').textContent='Error'; if(event.detail.response){event.detail.response.clone().text().then(function(t){event.target.closest('form').querySelector('[id$=errors]').innerHTML=t})}" (input :type "hidden" :name "csrf_token" :value csrf) (div :class "flex-1" (label :class "block text-sm text-gray-600" "Name") (input :name "name" :type "text" :required true :class "w-full border rounded px-3 py-2" :placeholder "e.g. Events, Gigs, Meetings")) (button :type "submit" :class "border rounded px-3 py-2" "Add calendar")))) (defcomp ~events-calendars-panel (&key form list) (section :class "p-4" form (div :id "calendars-list" :class "mt-6" list))) (defcomp ~events-calendars-empty () (p :class "text-gray-500 mt-4" "No calendars yet. Create one above.")) (defcomp ~events-calendars-item (&key href cal-name cal-slug del-url csrf-hdr) (div :class "mt-6 border rounded-lg p-4" (div :class "flex items-center justify-between gap-3" (a :class "flex items-baseline gap-3" :href href :sx-get href :sx-target "#main-panel" :sx-select "#main-panel" :sx-swap "outerHTML" :sx-push-url "true" (h3 :class "font-semibold" cal-name) (h4 :class "text-gray-500" (str "/" cal-slug "/"))) (button :class "text-sm border rounded px-3 py-1 hover:bg-red-50 hover:border-red-400" :data-confirm true :data-confirm-title "Delete calendar?" :data-confirm-text "Entries will be hidden (soft delete)" :data-confirm-icon "warning" :data-confirm-confirm-text "Yes, delete it" :data-confirm-cancel-text "Cancel" :data-confirm-event "confirmed" :sx-delete del-url :sx-trigger "confirmed" :sx-target "#calendars-list" :sx-select "#calendars-list" :sx-swap "outerHTML" :sx-headers csrf-hdr (i :class "fa-solid fa-trash"))))) (defcomp ~events-calendar-description-display (&key description edit-url) (div :id "calendar-description" (if description (p :class "text-stone-700 whitespace-pre-line break-all" description) (p :class "text-stone-400 italic" "No description yet.")) (button :type "button" :class "mt-2 text-xs underline" :sx-get edit-url :sx-target "#calendar-description" :sx-swap "outerHTML" (i :class "fas fa-edit")))) (defcomp ~events-calendar-description-title-oob (&key description) (div :id "calendar-description-title" :sx-swap-oob "outerHTML" :class "text-base font-normal break-words whitespace-normal min-w-0 break-all w-full text-center block" description)) (defcomp ~events-calendar-description-edit-form (&key save-url cancel-url csrf description) (div :id "calendar-description" (form :sx-post save-url :sx-target "#calendar-description" :sx-swap "outerHTML" (input :type "hidden" :name "csrf_token" :value csrf) (textarea :name "description" :autocomplete "off" :rows "4" :class "w-full p-2 border rounded" description) (div :class "mt-2 flex gap-2 text-xs" (button :type "submit" :class "px-3 py-1 rounded bg-stone-800 text-white" "Save") (button :type "button" :class "px-3 py-1 rounded border" :sx-get cancel-url :sx-target "#calendar-description" :sx-swap "outerHTML" "Cancel")))))