progress towards sales.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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-)
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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..."]]])])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]]])])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)))}]})
|
||||
|
||||
@@ -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"}]]]))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)}
|
||||
|
||||
Reference in New Issue
Block a user