From 160c289f0389b080d55ac59cc2579544107b594a Mon Sep 17 00:00:00 2001 From: Bryce Date: Tue, 26 Sep 2023 14:30:21 -0700 Subject: [PATCH] progress towards sales. --- resources/public/output.css | 114 +++++++++++++++--- src/clj/auto_ap/ssr/components.clj | 2 + src/clj/auto_ap/ssr/components/aside.clj | 5 +- src/clj/auto_ap/ssr/components/buttons.clj | 28 +++++ src/clj/auto_ap/ssr/components/data_grid.clj | 7 +- src/clj/auto_ap/ssr/components/inputs.clj | 29 +++-- src/clj/auto_ap/ssr/components/radio.clj | 20 ++- src/clj/auto_ap/ssr/grid_page_helper.clj | 50 ++++++-- src/clj/auto_ap/ssr/pos/sales_orders.clj | 85 ++++++++----- src/clj/auto_ap/ssr/ui.clj | 17 ++- src/clj/auto_ap/ssr/utils.clj | 11 +- .../auto_ap/views/components/layouts.cljs | 4 +- 12 files changed, 299 insertions(+), 73 deletions(-) diff --git a/resources/public/output.css b/resources/public/output.css index 24a68b5c..360a5025 100644 --- a/resources/public/output.css +++ b/resources/public/output.css @@ -1095,6 +1095,14 @@ input:checked + .toggle-bg { top: 1.25rem; } +.left-1\/2 { + left: 50%; +} + +.top-2\/4 { + top: 50%; +} + .z-10 { z-index: 10; } @@ -1324,6 +1332,10 @@ input:checked + .toggle-bg { height: 100vh; } +.h-56 { + height: 14rem; +} + .max-h-96 { max-height: 24rem; } @@ -1348,6 +1360,10 @@ input:checked + .toggle-bg { width: 1rem; } +.w-48 { + width: 12rem; +} + .w-5 { width: 1.25rem; } @@ -1368,8 +1384,8 @@ input:checked + .toggle-bg { width: 100%; } -.w-48 { - width: 12rem; +.w-56 { + width: 14rem; } .max-w-2xl { @@ -1437,6 +1453,16 @@ input:checked + .toggle-bg { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } +.-translate-x-1\/2 { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-1\/2 { + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + .rotate-180 { --tw-rotate: 180deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -1460,6 +1486,16 @@ input:checked + .toggle-bg { animation: spin 1s linear infinite; } +@keyframes pulse { + 50% { + opacity: .5; + } +} + +.animate-pulse { + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + .cursor-default { cursor: default; } @@ -1480,6 +1516,12 @@ input:checked + .toggle-bg { list-style-type: none; } +.appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } @@ -1670,6 +1712,10 @@ input:checked + .toggle-bg { border-radius: 0.5rem; } +.rounded-md { + border-radius: 0.375rem; +} + .rounded-l-lg { border-top-left-radius: 0.5rem; border-bottom-left-radius: 0.5rem; @@ -1876,11 +1922,6 @@ input:checked + .toggle-bg { --tw-bg-opacity: 0.5; } -.object-contain { - -o-object-fit: contain; - object-fit: contain; -} - .p-1 { padding: 0.25rem; } @@ -2095,6 +2136,10 @@ input:checked + .toggle-bg { line-height: 1.25; } +.leading-none { + line-height: 1; +} + .text-black { --tw-text-opacity: 1; color: rgb(0 0 0 / var(--tw-text-opacity)); @@ -2187,6 +2232,14 @@ input:checked + .toggle-bg { opacity: 1; } +.opacity-50 { + opacity: 0.5; +} + +.opacity-5 { + opacity: 0.05; +} + .shadow { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); @@ -2493,6 +2546,10 @@ input:checked + .toggle-bg { text-decoration-line: underline; } +.focus\:z-10:focus { + z-index: 10; +} + .focus\:border-blue-500:focus { --tw-border-opacity: 1; border-color: rgb(0 156 234 / var(--tw-border-opacity)); @@ -2503,6 +2560,11 @@ input:checked + .toggle-bg { border-color: rgb(121 181 46 / var(--tw-border-opacity)); } +.focus\:text-green-700:focus { + --tw-text-opacity: 1; + color: rgb(73 109 28 / var(--tw-text-opacity)); +} + .focus\:outline-none:focus { outline: 2px solid transparent; outline-offset: 2px; @@ -2555,6 +2617,11 @@ input:checked + .toggle-bg { --tw-ring-color: rgb(175 211 130 / var(--tw-ring-opacity)); } +.focus\:ring-green-700:focus { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(73 109 28 / var(--tw-ring-opacity)); +} + .focus\:ring-primary-500:focus { --tw-ring-opacity: 1; --tw-ring-color: rgb(121 181 46 / var(--tw-ring-opacity)); @@ -2766,6 +2833,11 @@ input:checked + .toggle-bg { color: rgb(250 202 21 / var(--tw-text-opacity)); } +:is(.dark .dark\:text-blue-200) { + --tw-text-opacity: 1; + color: rgb(153 215 247 / var(--tw-text-opacity)); +} + :is(.dark .dark\:placeholder-gray-400)::-moz-placeholder { --tw-placeholder-opacity: 1; color: rgb(156 163 175 / var(--tw-placeholder-opacity)); @@ -2776,14 +2848,14 @@ input:checked + .toggle-bg { color: rgb(156 163 175 / var(--tw-placeholder-opacity)); } -:is(.dark .dark\:ring-offset-gray-800) { - --tw-ring-offset-color: #1F2937; -} - :is(.dark .dark\:ring-offset-gray-700) { --tw-ring-offset-color: #374151; } +:is(.dark .dark\:ring-offset-gray-800) { + --tw-ring-offset-color: #1F2937; +} + :is(.dark .dark\:hover\:bg-blue-600:hover) { --tw-bg-opacity: 1; background-color: rgb(0 125 187 / var(--tw-bg-opacity)); @@ -2854,11 +2926,21 @@ input:checked + .toggle-bg { border-color: rgb(121 181 46 / var(--tw-border-opacity)); } +:is(.dark .dark\:focus\:text-white:focus) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + :is(.dark .dark\:focus\:ring-blue-500:focus) { --tw-ring-opacity: 1; --tw-ring-color: rgb(0 156 234 / var(--tw-ring-opacity)); } +:is(.dark .dark\:focus\:ring-blue-600:focus) { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(0 125 187 / var(--tw-ring-opacity)); +} + :is(.dark .dark\:focus\:ring-blue-800:focus) { --tw-ring-opacity: 1; --tw-ring-color: rgb(0 62 94 / var(--tw-ring-opacity)); @@ -2869,6 +2951,11 @@ input:checked + .toggle-bg { --tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity)); } +:is(.dark .dark\:focus\:ring-green-500:focus) { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(121 181 46 / var(--tw-ring-opacity)); +} + :is(.dark .dark\:focus\:ring-green-800:focus) { --tw-ring-opacity: 1; --tw-ring-color: rgb(48 72 18 / var(--tw-ring-opacity)); @@ -2884,11 +2971,6 @@ input:checked + .toggle-bg { --tw-ring-color: rgb(97 145 37 / var(--tw-ring-opacity)); } -:is(.dark .dark\:focus\:ring-blue-600:focus) { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(0 125 187 / var(--tw-ring-opacity)); -} - :is(.dark .dark\:focus\:ring-offset-gray-700:focus) { --tw-ring-offset-color: #374151; } diff --git a/src/clj/auto_ap/ssr/components.clj b/src/clj/auto_ap/ssr/components.clj index 9f9e1484..6904fafd 100644 --- a/src/clj/auto_ap/ssr/components.clj +++ b/src/clj/auto_ap/ssr/components.clj @@ -18,6 +18,8 @@ (def button-icon buttons/button-icon-) (def icon-button buttons/icon-button-) (def a-icon-button buttons/a-icon-button-) +(def button-group buttons/group-) +(def button-group-button buttons/group-button-) (def modal dialog/modal-) (def modal-card dialog/modal-card-) diff --git a/src/clj/auto_ap/ssr/components/aside.clj b/src/clj/auto_ap/ssr/components/aside.clj index 03b66b65..1d843d2c 100644 --- a/src/clj/auto_ap/ssr/components/aside.clj +++ b/src/clj/auto_ap/ssr/components/aside.clj @@ -178,8 +178,9 @@ :icon svg/receipt-register-1} "Sales") (sub-menu- {:id "dropdown-sales"} - (menu-button- {:href (bidi/path-for client-routes/routes - :sales-orders)} "Sales") + (menu-button- {:href (str (bidi/path-for client-routes/routes + :pos-sales) + "?date-range=week")} "Sales") (menu-button- {:href (bidi/path-for client-routes/routes :expected-deposits)} "Expected Deposits") #_(menu-button- {:href "Sales"} "Cash Shifts") diff --git a/src/clj/auto_ap/ssr/components/buttons.clj b/src/clj/auto_ap/ssr/components/buttons.clj index e323a833..1beef696 100644 --- a/src/clj/auto_ap/ssr/components/buttons.clj +++ b/src/clj/auto_ap/ssr/components/buttons.clj @@ -46,3 +46,31 @@ (svg/spinner {:class "inline w-4 h-4 text-white"}) [:div.ml-3 "Loading..."]] (into [:div.htmx-indicator-hidden ] children)]) + + + +(defn group-button- [{:keys [size] :or {size :normal} :as params} & children] + (into [:button (cond-> params + true (assoc :type (or (:type params) "button")) + true (update :class (fn [c] + (cond-> c + true (str " font-medium text-gray-900 bg-white border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-2 focus:ring-green-700 focus:text-green-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-green-500 dark:focus:text-white") + + (= :small size) + (str " text-xs px-3 py-2") + + (= :normal size) + (str " text-sm px-4 py-2") + ) + )) + true (dissoc :size))] children )) + +(defn group- [{:keys [name]} & children] + (let [children (-> children + vec + (update-in [0 1 :class] str " rounded-l-lg") + (update-in [(dec (count children)) 1 :class] str " rounded-r-lg"))] + (into [:div {:class "inline-flex rounded-md shadow-sm", :role "group" + :hx-on:click "this.querySelector(\"input\").value = event.target.value; this.querySelector(\"input\").dispatchEvent(new Event('change', {bubbles: true}));"} + [:input {:type "hidden" :name name}]] + children))) diff --git a/src/clj/auto_ap/ssr/components/data_grid.clj b/src/clj/auto_ap/ssr/components/data_grid.clj index 5625818e..8e4000d8 100644 --- a/src/clj/auto_ap/ssr/components/data_grid.clj +++ b/src/clj/auto_ap/ssr/components/data_grid.clj @@ -69,6 +69,7 @@ :hx-trigger "clientSelected from:body" :hx-swap "outerHTML swap:300ms" :id id} + (content-card- {} [:div {:class "flex flex-col px-4 py-3 space-y-3 lg:flex-row lg:items-center lg:justify-between lg:space-y-0 lg:space-x-4 text-gray-800 dark:text-gray-100"} @@ -97,4 +98,8 @@ :request-method :get) "?start=" (* page per-page)) :hx-target (str "#" id) - :hx-swap "outerHTML show:#app:top"})})))]) + :hx-swap "outerHTML show:#app:top" + :hx-indicator (str "#" id)})})) + [:div {:class "htmx-indicator absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2 overflow-hidden w-full h-full"} + [:div {:class "flex items-center justify-center w-full h-full border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-800 dark:border-gray-700 bg-opacity-50" } + [:div {:class "px-3 py-1 text-xs font-medium leading-none text-center text-blue-800 bg-blue-200 rounded-full animate-pulse dark:bg-blue-900 dark:text-blue-200"} "loading..."]]])]) diff --git a/src/clj/auto_ap/ssr/components/inputs.clj b/src/clj/auto_ap/ssr/components/inputs.clj index e781045a..3b069941 100644 --- a/src/clj/auto_ap/ssr/components/inputs.clj +++ b/src/clj/auto_ap/ssr/components/inputs.clj @@ -11,28 +11,39 @@ (:allow-blank? params) (conj [:option {:value "" :selected (not (:value params))} ""]))] children)) -(defn text-input- [params] +(defn use-size [size] + (if (= :small size) + (str " " "text-xs p-2") + (str " " "text-sm p-2.25"))) +(defn text-input- [{:keys [size] :as params}] [:input - (update params - :class str " bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500") + (-> params + (update + :class str " bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500") + (update :class #(str % (use-size size))) + ) ]) -(defn money-input- [params] +(defn money-input- [{:keys [size] :as params}] [:input (-> params (update - :class str " bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-right" + :class str " bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 text-right appearance-none" ) + (update :class #(str % (use-size size))) (assoc :type "number" - :step "0.01")) + :step "0.01") + (dissoc :size)) ]) -(defn date-input- [params] +(defn date-input- [{:keys [size] :as params}] [:input (-> params (update - :class str " bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500") - (assoc :type "date"))]) + :class str " bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500") + (assoc :type "date") + (update :class #(str % (use-size size))) + (dissoc :size))]) (defn field- [params & rest] (into diff --git a/src/clj/auto_ap/ssr/components/radio.clj b/src/clj/auto_ap/ssr/components/radio.clj index 150ef0fb..f9a701a3 100644 --- a/src/clj/auto_ap/ssr/components/radio.clj +++ b/src/clj/auto_ap/ssr/components/radio.clj @@ -1,6 +1,6 @@ (ns auto-ap.ssr.components.radio) -(defn radio- [{:keys [options name title]}] +(defn radio- [{:keys [options name title size] :or {size :medium}}] [:h3 {:class "mb-4 font-semibold text-gray-900 dark:text-white"} title] [:ul {:class "w-48 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white"} (for [{:keys [value content]} options] @@ -9,5 +9,19 @@ [:input {:id (str "list-" name "-" value) :type "radio", :value value - :name name :class "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"}] - [:label {:for (str "list-" name "-" value) :class "w-full py-3 ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"} content]]])]) + :name name + :class + (cond-> "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500" + (= size :small) + (str " " "text-xs") + + (= size :medium) + (str " " "text-sm"))}] + [:label {:for (str "list-" name "-" value) + :class + (cond-> "w-full ml-2 font-medium text-gray-900 dark:text-gray-300" + (= size :small) + (str " " "text-xs py-2") + + (= size :medium) + (str " " "text-sm py-3"))} content]]])]) diff --git a/src/clj/auto_ap/ssr/grid_page_helper.clj b/src/clj/auto_ap/ssr/grid_page_helper.clj index 357c7986..e444144f 100644 --- a/src/clj/auto_ap/ssr/grid_page_helper.clj +++ b/src/clj/auto_ap/ssr/grid_page_helper.clj @@ -10,7 +10,9 @@ [clojure.string :as str] [auto-ap.ssr.svg :as svg] [unilog.context :as lc] - [com.brunobonacci.mulog :as mu])) + [com.brunobonacci.mulog :as mu] + [auto-ap.time :as atime] + [clj-time.core :as time])) (defn row* [gridspec user entity {:keys [flash? delete-after-settle? params] :as options}] (let [cells (->> gridspec @@ -72,15 +74,16 @@ [entities total] ((:fetch-page grid-spec) user params)] + (com/data-grid-card {:id (:id grid-spec) :title (:title grid-spec) :route (:route grid-spec) :start start :per-page per-page :total total - :subtitle [:div.flex.items-center.gap-2 - [:span (format "Total %s: %d, " (:entity-name grid-spec) total)] - (sort-by-list grid-spec sort)] + :subtitle [:div.flex.items-center.gap-2 + [:span (format "Total %s: %d, " (:entity-name grid-spec) total)] + (sort-by-list grid-spec sort)] :action-buttons ((:action-buttons grid-spec) user params) :rows (for [entity entities] (row* grid-spec user entity {:flash? (= flash-id ((:id-fn grid-spec) entity)) :params params})) @@ -174,9 +177,33 @@ (update :sort sort->query) (url/map->query))) +(defn use-date-range [query-params date-range] + (condp = date-range + "week" + (assoc query-params + :start-date (atime/unparse-local (time/plus (time/now) (time/days -7)) atime/iso-date) + :end-date (atime/unparse-local (time/now) atime/iso-date)) + + "month" + (assoc query-params + :start-date (atime/unparse-local (time/plus (time/now) (time/months -1)) atime/iso-date) + :end-date (atime/unparse-local (time/now) atime/iso-date)) + + "year" + (assoc query-params + :start-date (atime/unparse-local (time/plus (time/now) (time/years -1)) atime/iso-date) + :end-date (atime/unparse-local (time/now) atime/iso-date)) + + "all" + (assoc query-params + :start-date (atime/unparse-local (time/plus (time/now) (time/years -3)) atime/iso-date) + :end-date (atime/unparse-local (time/now) atime/iso-date)) + + query-params)) + (defn extract-params [grid-spec {:keys [query-params hx-query-params identity session] :as request}] (let [{hx-start "start" hx-per-page "per-page" hx-sort "sort" } hx-query-params - {q-start "start" q-per-page "per-page" q-sort "sort" q-toggle-sort "toggle-sort" q-remove-sort "remove-sort"} query-params + {q-start "start" q-per-page "per-page" q-sort "sort" q-toggle-sort "toggle-sort" q-remove-sort "remove-sort" date-range "date-range"} query-params raw-query-params (merge (or hx-query-params {}) query-params) parsed-query-params (cond-> (into {} (map (fn [[k v]] [(keyword k) v]) raw-query-params)) @@ -184,11 +211,12 @@ q-start (assoc :start (some-> q-start not-empty (Long/parseLong ))) hx-per-page (assoc :per-page (some-> hx-per-page not-empty (Long/parseLong ))) q-per-page (assoc :per-page (some-> q-per-page not-empty (Long/parseLong ))) - hx-sort (assoc :sort (doto (parse-sort grid-spec hx-sort) println)) - q-sort (assoc :sort (doto (parse-sort grid-spec q-sort) println )) + hx-sort (assoc :sort (parse-sort grid-spec hx-sort)) + q-sort (assoc :sort (parse-sort grid-spec q-sort)) (not-empty q-toggle-sort) (update :sort #(toggle-sort grid-spec % q-toggle-sort) ) (not-empty q-remove-sort) (update :sort (fn [s] (filter (comp (complement #{q-remove-sort}) :sort-key) s)) ) - true (dissoc :toggle-sort :remove-sort))] + date-range (use-date-range date-range) + true (dissoc :toggle-sort :remove-sort :date-range))] {:raw-query-params raw-query-params :parsed-query-params parsed-query-params :client-selection (:client-selection (:session request)) @@ -202,7 +230,9 @@ grid-spec identity params) - :headers {"hx-push-url" (str "?" (params->query-string params))}))) + :headers {"hx-push-url" (str "?" (params->query-string params))} + :oob (when-let [oob-render (:oob-render grid-spec)] + (oob-render identity params))))) (defn page [grid-spec {:keys [identity] :as request}] (let [params (extract-params grid-spec request)] @@ -210,7 +240,7 @@ request (com/page {:nav (:nav grid-spec) :page-specific (when-let [page-specific-nav (:page-specific-nav grid-spec)] - (page-specific-nav params)) + [:div#page-specific-nav (page-specific-nav params)]) :client-selection (:client-selection (:session request)) :clients (:clients request) :client (:client request) diff --git a/src/clj/auto_ap/ssr/pos/sales_orders.clj b/src/clj/auto_ap/ssr/pos/sales_orders.clj index 48dbb610..24b95c91 100644 --- a/src/clj/auto_ap/ssr/pos/sales_orders.clj +++ b/src/clj/auto_ap/ssr/pos/sales_orders.clj @@ -14,40 +14,65 @@ ;; TODO refunds ;; TODO expected deposits ;; TODO loading screen -;; TODO default date range ;; always should be fast +;; make params parsing composable -(defn filters [params] - [:form {"hx-trigger" "change delay:1000ms" - "hx-get" (bidi/path-for ssr-routes/only-routes - :pos-sales-table) - "hx-target" "#sales-table"} - [:div.space-y-6 - [:div - (com/field {:label "Starting"} +(defn date-range-field* [params] + [:div#date-range {} + (com/field {:label "Date Range"} + [:div.space-y-4 + [:div + (com/button-group {:name "date-range"} + (com/button-group-button {:size :small :value "all" :hx-trigger "click"} "All") + (com/button-group-button {:size :small :value "week" :hx-trigger "click"} "Week") + (com/button-group-button {:size :small :value "month" :hx-trigger "click"} "Month") + (com/button-group-button {:size :small :value "year" :hx-trigger "click"} "Year")) + ] + [:div.flex.space-x-1.items-baseline (com/date-input {:name "start-date" :value (:start-date (:parsed-query-params params)) - :placeholder "Date"}))] - [:div - (com/field {:label "Ending"} + :placeholder "Date" + :size :small}) + (com/date-input {:name "end-date" :value (:end-date (:parsed-query-params params)) - :placeholder "Date"}))] + :placeholder "Date" + :size :small})]] + )]) +(defn filters [params] + [:form {"hx-trigger" "change delay:500ms, keyup from:.hot-filter delay:1000ms" + "hx-get" (bidi/path-for ssr-routes/only-routes + :pos-sales-table) + "hx-target" "#sales-table" + "hx-indicator" "#sales-table" + #_#_:hx-disabled-elt "find fieldset"} + + [:fieldset.space-y-6 + (date-range-field* params) [:div (com/field {:label "Total"} [:div.flex.space-x-4.items-baseline (com/money-input {:name "total-gte" + :id "total-gte" + :hx-preserve "true" + :class "hot-filter" :value (:total-gte (:parsed-query-params params)) - :placeholder "0.01"}) + :placeholder "0.01" + :size :small}) [:div.align-baseline "to"] (com/money-input {:name "total-lte" + :hx-preserve "true" + :id "total-lte" + :class "hot-filter" :value (:total-lte (:parsed-query-params params)) - :placeholder "9999.34"})])] + :placeholder "9999.34" + :size :small})])] [:div (com/field {:label "Payment Method"} - (com/radio {:name "payment-method" - :options [{:value "all" + (com/radio {:size :small + :name "payment-method" + :options [{:value "all" :content "All"} {:value "cash" :content "Cash"} @@ -61,7 +86,8 @@ [:div (com/field {:label "Processor"} - (com/radio {:name "processor" + (com/radio {:size :small + :name "processor" :options [{:value "" :content "All"} {:value "square" @@ -81,10 +107,14 @@ ]}))] [:div - (com/field {:label "Total"} + (com/field {:label "Category"} (com/text-input {:name "category" + :class "hot-filter" + :id "category" + :hx-preserve "true" :value (:category (:parsed-query-params params)) - :placeholder "Fries"}))]]]) + :placeholder "Fries" + :size :small}))]]]) (defn args->graphql-params [args] {:clients (:clients args) @@ -93,12 +123,12 @@ :per-page (:per-page (:parsed-query-params args)) :category (not-empty (:category (:parsed-query-params args))) :date-range {:start (some-> args - :raw-query-params - (get "start-date") + :parsed-query-params + :start-date (atime/parse atime/iso-date)) :end (some-> args - :raw-query-params - (get "end-date") + :parsed-query-params + :end-date (atime/parse atime/iso-date))} :total-gte (some-> args :raw-query-params (get "total-gte") not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) :total-lte (some-> args :raw-query-params (get "total-lte") not-empty (#(if (string? %) (Double/parseDouble %) (double %)))) @@ -118,8 +148,10 @@ :id-fn :db/id :fetch-page (fn [user args] (d-sales/get-graphql - (args->graphql-params args) - )) + (args->graphql-params args))) + :oob-render + (fn [user params] + [(assoc-in (date-range-field* params) [1 :hx-swap-oob] true)]) :breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes :company)} "POS"] @@ -183,7 +215,6 @@ {:key "Payment methods" :name "Payment Methods" :render (fn [sales-order] - (println ) (for [method (->> sales-order :sales-order/charges (map :charge/type-name) set)] (com/pill {:color :primary } method)))}]}) diff --git a/src/clj/auto_ap/ssr/ui.clj b/src/clj/auto_ap/ssr/ui.clj index c2f72c99..ff836c55 100644 --- a/src/clj/auto_ap/ssr/ui.clj +++ b/src/clj/auto_ap/ssr/ui.clj @@ -30,7 +30,7 @@ #_[:script {:src "https://unpkg.com/htmx.org@1.8.4" :integrity "sha384-wg5Y/JwF7VxGk4zLsJEcAojRtlVp1FKKdGy1qN+OMtdq72WRvX/EdRdqg/LOhYeV" :crossorigin= "anonymous"}] - [:script {:src "https://unpkg.com/htmx.org@1.9.0/dist/htmx.js" + [:script {:src "https://unpkg.com/htmx.org@1.9.6/dist/htmx.min.js" :crossorigin= "anonymous"}] [:script {:src "https://unpkg.com/htmx.org/dist/ext/debug.js"}] [:script {:src "/js/htmx-disable.js"}] @@ -38,6 +38,21 @@ [:script {:type "text/javascript", :src "https://cdn.jsdelivr.net/npm/@tarekraafat/autocomplete.js@10.2.7/dist/autoComplete.min.js"}] [:script {:src "https://unpkg.com/dropzone@5.9.3/dist/min/dropzone.min.js"}] [:link {:rel "stylesheet" :href "https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" :type "text/css"}] + [: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"} contents [:script {:src "/js/flowbite.min.js"}]]])) diff --git a/src/clj/auto_ap/ssr/utils.clj b/src/clj/auto_ap/ssr/utils.clj index 929d5d64..df5d8968 100644 --- a/src/clj/auto_ap/ssr/utils.clj +++ b/src/clj/auto_ap/ssr/utils.clj @@ -5,14 +5,21 @@ [hiccup2.core :as hiccup] [clojure.string :as str])) -(defn html-response [hiccup & {:keys [status headers] :or {status 200 headers {}}}] +(defn html-response [hiccup & {:keys [status headers oob] :or {status 200 headers {} oob []}}] {:status status :headers (into {"Content-Type" "text/html"} headers) :body (str (hiccup/html {} - hiccup))}) + hiccup) + "\n" + (str/join "\n" + (map (fn [o] + (hiccup/html + {} + o)) + oob)))}) (defn wrap-error-response [handler] (fn [request] diff --git a/src/cljs/auto_ap/views/components/layouts.cljs b/src/cljs/auto_ap/views/components/layouts.cljs index e74cf2e3..1b8c0eb6 100644 --- a/src/cljs/auto_ap/views/components/layouts.cljs +++ b/src/cljs/auto_ap/views/components/layouts.cljs @@ -173,8 +173,8 @@ :href (bidi/path-for routes/routes :payments)} "Payments" ] (when (= "admin" (:user/role @user)) - [:a.navbar-item {:class [(active-when ap = :sales-orders)] - :href (bidi/path-for routes/routes :sales-orders)} + [:a.navbar-item {:class [(active-when ap = :pos-sales)] + :href (str (bidi/path-for ssr-routes/only-routes :pos-sales) "?date-range=week")} "POS" ]) [:a.navbar-item {:class [(active-when ap = :transactions)] :href (bidi/path-for routes/routes :transactions)}