The admin page was the only consumer of Chartist while the dashboard and expense report already use Chart.js. Convert the admin "Growth in clients" (bar) and "Changes by hour" (line) charts to Chart.js using the same Alpine x-data/x-init canvas pattern as the dashboard, and drop the global Chartist CSS/JS includes from the base page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
106 lines
5.6 KiB
Clojure
106 lines
5.6 KiB
Clojure
(ns auto-ap.ssr.ui
|
|
(:require
|
|
[auto-ap.ssr.hx :as hx]
|
|
[config.core :refer [env]]
|
|
[hiccup2.core :as hiccup]
|
|
[auto-ap.ssr.components :as com]))
|
|
(defn html-page [hiccup]
|
|
{:status 200
|
|
:headers {"Content-Type" "text/html"}
|
|
:body (str
|
|
"<!DOCTYPE html>"
|
|
(hiccup/html
|
|
{}
|
|
hiccup))})
|
|
|
|
(defn base-page [request contents page-name]
|
|
(html-page
|
|
[:html
|
|
[:head
|
|
[:meta {:charset "utf-8"}]
|
|
[:meta {:http-equiv "X-UA-Compatible", :content "IE=edge"}]
|
|
[:meta {:name "viewport", :content "width=device-width, initial-scale=1"}]
|
|
[:title (str "Integreat | " page-name)]
|
|
[:link {:href "/css/font.min.css", :rel "stylesheet"}]
|
|
[:link {:rel "icon" :type "image/png" :href "/favicon.png"}]
|
|
[:link {:rel "stylesheet", :href "/output.css"}]
|
|
[:script {:src "https://cdn.plaid.com/link/v2/stable/link-initialize.js"}]
|
|
[:script {:src "https://cdn.jsdelivr.net/npm/@ryangjchandler/alpine-tooltip@1.x.x/dist/cdn.min.js" :defer true}]
|
|
[:link {:rel "stylesheet" :href "/css/tippy/tippy.css"}]
|
|
[:link {:rel "stylesheet" :href "/css/tippy/light.css"}]
|
|
[:script {:src "/js/htmx.js"
|
|
:crossorigin= "anonymous"}]
|
|
|
|
[:script {:src "https://cdn.jsdelivr.net/npm/sortablejs@1.15.2/Sortable.min.js"}]
|
|
[:script {:src "/js/htmx-disable.js"}]
|
|
[:script {:type "text/javascript", :src "https://cdn.yodlee.com/fastlink/v4/initialize.js", :async "async"}]]
|
|
[:link {:rel "stylesheet" :href "https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.3.4/dist/css/datepicker.min.css"}]
|
|
[:script {:type "text/javascript" :src "https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.3.4/dist/js/datepicker-full.min.js"}]
|
|
[:script {:src "https://unpkg.com/htmx.org/dist/ext/response-targets.js" :defer true}]
|
|
[:script {:src "https://cdn.jsdelivr.net/npm/date-fns@3.6.0/cdn.min.js" :defer true}]
|
|
[:script {:src "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js" :integrity "sha512-CQBWl4fJHWbryGE+Pc7UAxWMUMNMWzWxF4SQo9CgkJIN1kx6djDQZjh3Y8SZ1d+6I+1zze6Z7kHXO7q3UyZAWw==" :crossorigin "anonymous" :referrerpolicy "no-referrer"}]
|
|
|
|
[:script {:src "https://unpkg.com/dropzone@5.9.3/dist/min/dropzone.min.js" :defer true}]
|
|
[:link {:rel "stylesheet" :href "https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" :type "text/css" :defer true}]
|
|
[:script {:defer true :src "/js/alpine-vals.js"}]
|
|
[:script {:defer true :src "https://cdn.jsdelivr.net/npm/@ryangjchandler/alpine-clipboard@2.x.x/dist/alpine-clipboard.js"}]
|
|
[:script {:defer true :src "https://cdn.jsdelivr.net/npm/@alpinejs/focus@3.x.x/dist/cdn.min.js"}]
|
|
[:script {:defer true :src "https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"}]
|
|
[:script {:src "https://cdn.jsdelivr.net/npm/signature_pad@4.1.7/dist/signature_pad.umd.min.js"}]
|
|
[:script {:src "https://cdn.jsdelivr.net/npm/jdenticon@3.3.0/dist/jdenticon.min.js" :async true :defer true :integrity "sha384-LfouGM03m83ArVtne1JPk926e3SGD0Tz8XHtW2OKGsgeBU/UfR0Fa8eX+UlwSSAZ" :crossorigin "anonymous"}]
|
|
|
|
[:style
|
|
"
|
|
input::-webkit-outer-spin-button,
|
|
input::-webkit-inner-spin-button {
|
|
/* display: none; <- Crashes Chrome on hover */
|
|
-webkit-appearance: none;
|
|
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
|
|
}
|
|
input[type=number] {
|
|
-moz-appearance:textfield; /* Firefox */
|
|
} "]
|
|
[:body {:hx-ext "disable-submit"
|
|
":class" "$store.darkMode.on && 'dark'"
|
|
:x-data (hx/json {:globalClientSelection (or (:client-selection request)
|
|
:all)}) ;; TODO remove once session is used
|
|
:x-hx-header:x-clients "JSON.stringify(globalClientSelection)"}
|
|
contents
|
|
[:script {:src "/js/flowbite.min.js"}]
|
|
|
|
[:div#modal-holder
|
|
{:class "fixed top-0 left-0 z-[99] flex items-center justify-center w-screen h-screen"
|
|
"x-show" "open"
|
|
":aria-hidden" "!open"
|
|
"x-data" (hx/json {"open" false
|
|
"forceBackground" false
|
|
"unexpectedError" false})
|
|
"x-on:htmx:response-error" "unexpectedError=true;"
|
|
"x-on:htmx:before-request" "unexpectedError=false"
|
|
"@modalopen.document" "open=true; unexpectedError=null"
|
|
"@modalclose.document" "open=false"
|
|
"@modalswap.document" "forceBackground=true; open=false; setTimeout(() => {open=true;forceBackground=false;}, 100)"}
|
|
|
|
[:div {:class "bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40 md:p-12"
|
|
"x-show" "open || forceBackground"
|
|
":aria-hidden" "!open"
|
|
"x-transition:enter" "duration-300"
|
|
"x-transition:enter-start" "!bg-opacity-0"
|
|
"x-transition:enter-end" "!bg-opacity-50"
|
|
"x-transition:leave" "duration-300"
|
|
"x-transition:leave-start" "!bg-opacity-50"
|
|
"x-transition:leave-end" "!bg-opacity-0"}
|
|
|
|
[:div {:class "flex h-full w-full justify-stretch md:justify-center items-stretch md:items-center "
|
|
"x-trap.inert.noscroll" "open"
|
|
"x-trap.inert" "open"
|
|
"x-show" "open"
|
|
"x-transition:enter" "ease-out duration-300"
|
|
"x-transition:enter-start" "!bg-opacity-0 !translate-y-32"
|
|
"x-transition:enter-end" "!bg-opacity-100 !translate-y-0"
|
|
"x-transition:leave" "duration-300"
|
|
"x-transition:leave-start" "!opacity-100 !translate-y-0"
|
|
"x-transition:leave-end" "!opacity-0 !translate-y-32"}
|
|
|
|
[:div#modal-content.flex.items-center.justify-center {:class "md:p-12"}]]]]]]))
|