From 1f6395382d6f1f1a5f00a3a3d632a654066a3cb6 Mon Sep 17 00:00:00 2001 From: Bryce Date: Tue, 2 Jun 2026 07:55:47 -0700 Subject: [PATCH] refactor(charts): unify on Chart.js, remove Chartist 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 --- src/clj/auto_ap/ssr/admin.clj | 81 ++++++++++++++++++++++++----------- src/clj/auto_ap/ssr/ui.clj | 2 - 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/clj/auto_ap/ssr/admin.clj b/src/clj/auto_ap/ssr/admin.clj index 687010ad..334534d9 100644 --- a/src/clj/auto_ap/ssr/admin.clj +++ b/src/clj/auto_ap/ssr/admin.clj @@ -10,8 +10,7 @@ [bidi.bidi :as bidi] [clj-time.coerce :as coerce] [clj-time.core :as time] - [datomic.api :as dc] - [hiccup2.core :as hiccup])) + [datomic.api :as dc])) (defn hourly-changes [] (let [tx-instant-attr (:db/id (dc/pull (dc/db conn) '[:db/id] :db/txInstant)) @@ -56,34 +55,68 @@ [:div [:h1.text-2xl.mb-3.font-bold "Growth in clients"] [:div - [:div {:class "w-full h-64" - :id "client-chart" - :data-chart (hx/json {:labels ["2 years ago" "1 year ago" "today"], - :series [(for [n [2 1 0] - :let [start (time/plus (time/now) (time/years (- n)))]] - (->> (dc/q '[:find (count ?c) - :in $ - :where [?c :client/code]] - (dc/as-of (dc/db conn) (coerce/to-date start))) - first - first))]})}] - [:script {:lang "javascript"} - (hiccup/raw - "new Chartist.Bar('#client-chart', JSON.parse(document.getElementById('client-chart').getAttribute('data-chart')))")]]]]) + [:div.w-full.h-64 + [:canvas.w-full.h-full {:x-data (hx/json {:chart nil + :labels ["2 years ago" "1 year ago" "today"] + :data (for [n [2 1 0] + :let [start (time/plus (time/now) (time/years (- n)))]] + (->> (dc/q '[:find (count ?c) + :in $ + :where [?c :client/code]] + (dc/as-of (dc/db conn) (coerce/to-date start))) + first + first))}) + :x-init "new Chart($el, { + type: 'bar', + data: { + labels: labels, + datasets: [{ + label: 'Clients', + data: data, + borderWidth: 1 + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: true + } + } + } + });"}]]]]]) (com/content-card {:class "w-1/2"} [:div {:class "flex flex-col px-4 py-3 space-y-3"} [:div [:h1.text-2xl.mb-3.font-bold "Changes by hour"] [:div - [:div {:class "w-full h-64" - :id "changes" - :data-chart (hx/json {:labels (for [n (range -24 0)] - (format "%d" n)), - :series [(hourly-changes)]})}] - [:script {:lang "javascript"} - (hiccup/raw - "new Chartist.Line('#changes', JSON.parse(document.getElementById('changes').getAttribute('data-chart')))")]]]])]) + [:div.w-full.h-64 + [:canvas.w-full.h-full {:x-data (hx/json {:chart nil + :labels (for [n (range -24 0)] + (format "%d" n)) + :data (hourly-changes)}) + :x-init "new Chart($el, { + type: 'line', + data: { + labels: labels, + datasets: [{ + label: 'Changes', + data: data, + borderWidth: 1 + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: true + } + } + } + });"}]]]]])]) "Admin")) (def key->handler diff --git a/src/clj/auto_ap/ssr/ui.clj b/src/clj/auto_ap/ssr/ui.clj index f9525ccc..d98e0fe0 100644 --- a/src/clj/auto_ap/ssr/ui.clj +++ b/src/clj/auto_ap/ssr/ui.clj @@ -23,8 +23,6 @@ [: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 "//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css"}] - [:script {:src "//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"}] [: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}]