tailwind ready
This commit is contained in:
@@ -20,18 +20,18 @@
|
||||
(:jwt-secret env)
|
||||
{:alg :hs512}))
|
||||
|
||||
(defn oauth [{{:strs [code]} :query-params {:strs [host]} :headers}]
|
||||
(defn oauth [{{:strs [code state]} :query-params {:strs [host]} :headers :as request}]
|
||||
(try
|
||||
(let [auth (-> "https://accounts.google.com/o/oauth2/token"
|
||||
(http/post
|
||||
{:form-params {"client_id" google-client-id
|
||||
"client_secret" google-client-secret
|
||||
"code" code
|
||||
"redirect_uri" (str (:scheme env) "://" host "/api/oauth")
|
||||
"grant_type" "authorization_code"}
|
||||
:as :json})
|
||||
(http/post
|
||||
{:form-params {"client_id" google-client-id
|
||||
"client_secret" google-client-secret
|
||||
"code" code
|
||||
"redirect_uri" (str (:scheme env) "://" host "/api/oauth")
|
||||
"grant_type" "authorization_code"}
|
||||
:as :json})
|
||||
:body)
|
||||
|
||||
|
||||
token (:access_token auth)
|
||||
profile (-> (http/get "https://www.googleapis.com/oauth2/v1/userinfo"
|
||||
{:headers {"Authorization" (str "Bearer " token)} :as :json})
|
||||
@@ -54,19 +54,18 @@
|
||||
_ (mu/log ::logged-in-as
|
||||
:auth auth)]
|
||||
;; TODO - these namespaces are not being transmitted/deserialized properly
|
||||
|
||||
|
||||
(if (and token user)
|
||||
(let [jwt (jwt/sign auth
|
||||
(:jwt-secret env)
|
||||
{:alg :hs512})]
|
||||
|
||||
{:status 301
|
||||
:headers {"Location" (str "/?jwt=" jwt)}
|
||||
:headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)}
|
||||
:session {:identity (dissoc auth :exp)}})
|
||||
{:status 401
|
||||
:body "Couldn't authenticate"}))
|
||||
(catch Exception e
|
||||
(log/warn e )
|
||||
(log/warn e)
|
||||
{:status 401
|
||||
:body (str "Couldn't authenticate " (.toString e))})))
|
||||
|
||||
|
||||
@@ -8,30 +8,33 @@
|
||||
(defn wrap-secure [handler]
|
||||
(fn [request]
|
||||
(cond (authenticated? request)
|
||||
(handler request)
|
||||
(handler request)
|
||||
|
||||
(get (:headers request) "hx-request")
|
||||
{:status 401
|
||||
:headers {"hx-redirect" (str "/login?"
|
||||
(url/map->query {"redirect-to" (:uri request)}))}}
|
||||
|
||||
(get (:headers request) "hx-request")
|
||||
{:status 401
|
||||
:headers {"hx-redirect" "/login"}}
|
||||
|
||||
:else
|
||||
{:status 302
|
||||
:headers {"Location" "/login" }})))
|
||||
:else
|
||||
{:status 302
|
||||
:headers {"Location" (str "/login?"
|
||||
(url/map->query {"redirect-to" (:uri request)}))}})))
|
||||
|
||||
(defn wrap-admin [handler]
|
||||
(fn [request]
|
||||
(if (is-admin? (:identity request))
|
||||
(handler request)
|
||||
(do
|
||||
(do
|
||||
(alog/warn ::unauthenticated)
|
||||
{:status 302
|
||||
:headers {"Location" "/login"}}))))
|
||||
:headers {"Location" (str "/login?"
|
||||
(url/map->query {"redirect-to" (:uri request)}))}}))))
|
||||
|
||||
(defn wrap-client-redirect-unauthenticated [handler]
|
||||
(fn [request]
|
||||
(let [response (handler request)]
|
||||
(if (= 401 (get response :status))
|
||||
(-> response
|
||||
(assoc-in [:headers "hx-redirect"] "/login/"))
|
||||
(-> response
|
||||
(assoc-in [:headers "hx-redirect"] (str "/login?"
|
||||
(url/map->query {"redirect-to" (:uri request)}))))
|
||||
response))))
|
||||
|
||||
@@ -126,16 +126,17 @@ function initCompanyDropdown() {
|
||||
|
||||
(defn active-client [{:keys [identity params] :as request}]
|
||||
(let [client-id (some-> (or (:search-client params) (get params "search-client")) not-empty Long/parseLong)]
|
||||
(println (format "HERE CLIENT ID '%s'" client-id))
|
||||
(when client-id
|
||||
(assert-can-see-client identity client-id))
|
||||
(let [new-session (assoc (:session request) :client
|
||||
(when client-id
|
||||
(dc/pull (dc/db conn) [:db/id :client/name :client/code] client-id)))]
|
||||
(assoc
|
||||
(html-response
|
||||
(dropdown {:client (:client new-session)
|
||||
:identity identity}))
|
||||
:session
|
||||
new-session
|
||||
:headers
|
||||
{"hx-trigger" "clientSelected"}))))
|
||||
(assoc
|
||||
(html-response
|
||||
(dropdown {:client (:client new-session)
|
||||
:identity identity}))
|
||||
:session
|
||||
new-session
|
||||
:headers
|
||||
{"hx-trigger" "clientSelected"}))))
|
||||
|
||||
@@ -150,69 +150,90 @@
|
||||
(defn main-aside-nav- []
|
||||
[:ul {:class "space-y-2"}
|
||||
|
||||
[:li
|
||||
(menu-button- {:icon svg/pie}
|
||||
"Dashboard")]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-invoices",
|
||||
:data-collapse-toggle "dropdown-invoices"
|
||||
:icon svg/accounting-invoice-mail}
|
||||
"Invoices")
|
||||
(sub-menu- {:id "dropdown-invoices"}
|
||||
(menu-button- {:href "http://google.com"}
|
||||
"All")
|
||||
(menu-button- {:href "http://google.com"}
|
||||
"Paid")
|
||||
(menu-button- {:href "http://google.com"}
|
||||
"Unpaid")
|
||||
(menu-button- {:href "http://google.com"}
|
||||
"Voided"))
|
||||
]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-sales",
|
||||
:data-collapse-toggle "dropdown-sales"
|
||||
:icon svg/receipt-register-1}
|
||||
"Sales")
|
||||
(sub-menu- {:id "dropdown-sales"}
|
||||
(menu-button- {:href "Sales"} "Sales")
|
||||
(menu-button- {:href "Sales"} "Expected Deposits")
|
||||
(menu-button- {:href "Sales"} "Cash Shifts")
|
||||
(menu-button- {:href "Sales"} "Tenders"))]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-payments"
|
||||
:data-collapse-toggle "dropdown-payments"
|
||||
:icon svg/payments}
|
||||
"Payments")
|
||||
(sub-menu- {:id "dropdown-payments"}
|
||||
(menu-button- {:href "Sales"} "All")
|
||||
(menu-button- {:href "Sales"} "Pending")
|
||||
(menu-button- {:href "Sales"} "Cleared")
|
||||
(menu-button- {:href "Sales"} "Voided"))]
|
||||
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-transactions"
|
||||
:data-collapse-toggle "dropdown-transactions"
|
||||
:icon svg/bank}
|
||||
"Transactions")
|
||||
|
||||
(sub-menu- {:id "dropdown-transactions"}
|
||||
(menu-button- {:href "Sales"} "All")
|
||||
(menu-button- {:href "Sales"} "Unapproved")
|
||||
(menu-button- {:href "Sales"} "Client Review")
|
||||
(menu-button- {:href "Sales"} "Approved")
|
||||
(menu-button- {:href "Sales"} "Insights"))]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-ledger"
|
||||
:data-collapse-toggle "dropdown-ledger"
|
||||
:icon svg/receipt}
|
||||
"Ledger")
|
||||
(sub-menu- {:id "dropdown-ledger"}
|
||||
(menu-button- {:href "Sales"} "Register")
|
||||
(menu-button- {:href "Sales"} "Profit & Loss")
|
||||
(menu-button- {:href "Sales"} "Profit & Loss Detail")
|
||||
(menu-button- {:href "Sales"} "Cash Flows")
|
||||
(menu-button- {:href "Sales"} "Balance Sheet")
|
||||
(menu-button- {:href "Sales"} "External Ledger Import"))]])
|
||||
[:li
|
||||
(menu-button- {:icon svg/pie
|
||||
:href "/"}
|
||||
"Dashboard")]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-invoices",
|
||||
:data-collapse-toggle "dropdown-invoices"
|
||||
:icon svg/accounting-invoice-mail}
|
||||
"Invoices")
|
||||
(sub-menu- {:id "dropdown-invoices"}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:invoices)}
|
||||
"All")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:paid-invoices)}
|
||||
"Paid")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:unpaid-invoices)}
|
||||
"Unpaid")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:voided-invoices)}
|
||||
"Voided"))]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-sales",
|
||||
:data-collapse-toggle "dropdown-sales"
|
||||
: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 (bidi/path-for client-routes/routes
|
||||
:expected-deposits)} "Expected Deposits")
|
||||
#_(menu-button- {:href "Sales"} "Cash Shifts")
|
||||
#_(menu-button- {:href "Sales"} "Tenders"))]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-payments"
|
||||
:data-collapse-toggle "dropdown-payments"
|
||||
:icon svg/payments}
|
||||
"Payments")
|
||||
(sub-menu- {:id "dropdown-payments"}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:payments)} "All")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:payments)} "Pending")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:payments)} "Cleared")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:payments)} "Voided"))]
|
||||
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-transactions"
|
||||
:data-collapse-toggle "dropdown-transactions"
|
||||
:icon svg/bank}
|
||||
"Transactions")
|
||||
|
||||
(sub-menu- {:id "dropdown-transactions"}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:transactions)} "All")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:unapproved-transactions)} "Unapproved")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:requires-feedback-transactions)} "Client Review")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:approved-transactions)} "Approved")
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
:transaction-insights)} "Insights"))]
|
||||
[:li
|
||||
(menu-button- {:aria-controls "dropdown-ledger"
|
||||
:data-collapse-toggle "dropdown-ledger"
|
||||
:icon svg/receipt}
|
||||
"Ledger")
|
||||
(sub-menu- {:id "dropdown-ledger"}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:ledger)} "Register")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss)} "Profit & Loss")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss-detail)} "Profit & Loss Detail")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:cash-flows)} "Cash Flows")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:balance-sheet)} "Balance Sheet")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:external-import-ledger)} "External Ledger Import"))]])
|
||||
|
||||
|
||||
(defn company-aside-nav- []
|
||||
@@ -301,3 +322,5 @@
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
:admin-ezcater-xls)
|
||||
:hx-boost "true"} "EZCater XLS Import"))]])
|
||||
|
||||
|
||||
|
||||
@@ -1,50 +1,45 @@
|
||||
(ns auto-ap.ssr.components.navbar
|
||||
(:require
|
||||
[auto-ap.datomic :refer [conn pull-attr]]
|
||||
[auto-ap.client-routes :as client-routes2]
|
||||
[auto-ap.graphql.utils :refer [is-admin?]]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.company-dropdown :as cd]
|
||||
[auto-ap.ssr.components.buttons :refer [icon-button-]]
|
||||
[auto-ap.ssr.components.user-dropdown :as user-dropdown]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[bidi.bidi :as bidi]
|
||||
[datomic.api :as dc]
|
||||
[hiccup2.core :as hiccup]
|
||||
[auto-ap.ssr.components.user-dropdown :as user-dropdown]))
|
||||
[bidi.bidi :as bidi]))
|
||||
|
||||
(defn navbar- [{:keys [client identity]}]
|
||||
[:nav {:class "fixed z-30 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700"}
|
||||
[:div {:class "px-3 py-3 lg:px-5 lg:pl-3"}
|
||||
[:div {:class "flex items-center justify-between"}
|
||||
[:div {:class "flex items-center justify-start"}
|
||||
[:button { :aria-controls "left-nav", :id "left-nav-toggle" :type "button", :class "inline-flex items-center p-2 mt-2 ml-2 mr-2 text-sm text-gray-500 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"}
|
||||
[:span {:class "sr-only"} "Open sidebar"]
|
||||
[:svg {:class "w-6 h-6", :aria-hidden "true", :fill "currentColor", :viewbox "0 0 20 20", :xmlns "http://www.w3.org/2000/svg"}
|
||||
[:path {:clip-rule "evenodd", :fill-rule "evenodd", :d "M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"}]]]
|
||||
[:a {:href "/" :class "flex ml-2 md:mr-24"}
|
||||
[:img {:src "/img/logo-big2.png", :class "h-10 mr-16", :alt "Integreat logo"}]
|
||||
]
|
||||
]
|
||||
|
||||
[:div {:class "flex items-center gap-4"}
|
||||
[:button.mt-1.lg:w-96.relative.hidden.lg:block {:class "bg-gray-50 hover:bg-gray-200 dark:hover:bg-gray-700 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 w-full pl-10 py-4 pr-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 gap-4 "
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
:search)
|
||||
:hx-target "#modal-holder"
|
||||
:hx-swap "outerHTML"}
|
||||
[:div {:class "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-gray-500"}
|
||||
[:div.w-4.h-4 svg/search]
|
||||
[:span.ml-2 "Search"]]]
|
||||
[:div {:class "hidden mr-3 -mb-1 sm:block"}
|
||||
[:span]]
|
||||
(icon-button-
|
||||
{:id "toggleSidebarMobileSearch", :type "button", :class "p-2 text-gray-500 rounded-lg lg:hidden hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
:search)
|
||||
:hx-target "#modal-holder"
|
||||
:hx-swap "outerHTML"}
|
||||
svg/search)
|
||||
(cd/dropdown {:client client :identity identity})
|
||||
|
||||
|
||||
(user-dropdown/dropdown {:identity identity})
|
||||
]]]])
|
||||
[:div {:class "flex items-center justify-between"}
|
||||
[:div {:class "flex items-center justify-start"}
|
||||
[:button {:aria-controls "left-nav", :id "left-nav-toggle" :type "button", :class "inline-flex items-center p-2 mt-2 ml-2 mr-2 text-sm text-gray-500 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"}
|
||||
[:span {:class "sr-only"} "Open sidebar"]
|
||||
[:svg {:class "w-6 h-6", :aria-hidden "true", :fill "currentColor", :viewbox "0 0 20 20", :xmlns "http://www.w3.org/2000/svg"}
|
||||
[:path {:clip-rule "evenodd", :fill-rule "evenodd", :d "M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"}]]]
|
||||
[:a {:href "/" :class "flex ml-2 md:mr-24"}
|
||||
[:img {:src "/img/logo-big2.png", :class "h-10 mr-16", :alt "Integreat logo"}]]]
|
||||
|
||||
[:div {:class "flex items-center gap-4"}
|
||||
|
||||
(when (is-admin? identity)
|
||||
[:button.mt-1.lg:w-96.relative.hidden.lg:block {:class "bg-gray-50 hover:bg-gray-200 dark:hover:bg-gray-700 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 w-full pl-10 py-4 pr-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 gap-4 "
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
:search)
|
||||
:hx-target "#modal-holder"
|
||||
:hx-swap "outerHTML"}
|
||||
[:div {:class "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-gray-500"}
|
||||
[:div.w-4.h-4 svg/search]
|
||||
[:span.ml-2 "Search"]]])
|
||||
[:div {:class "hidden mr-3 -mb-1 sm:block"}
|
||||
[:span]]
|
||||
(icon-button-
|
||||
{:id "toggleSidebarMobileSearch", :type "button", :class "p-2 text-gray-500 rounded-lg lg:hidden hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
:search)
|
||||
:hx-target "#modal-holder"
|
||||
:hx-swap "outerHTML"}
|
||||
svg/search)
|
||||
(cd/dropdown {:client client :identity identity})
|
||||
|
||||
(user-dropdown/dropdown {:identity identity})]]]])
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
:admin-history (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page)))
|
||||
:admin-history-search (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/page)))
|
||||
:admin-history-inspect (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin history/inspect)))
|
||||
:active-client (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin company-dropdown/active-client)))
|
||||
:active-client (wrap-client-redirect-unauthenticated (wrap-secure (wrap-secure company-dropdown/active-client)))
|
||||
:company-dropdown-search-results
|
||||
(wrap-client-redirect-unauthenticated (wrap-secure company-dropdown/dropdown-search-results))
|
||||
:company (wrap-client-redirect-unauthenticated (wrap-secure company/page))
|
||||
@@ -35,11 +35,11 @@
|
||||
:company-reports (wrap-client-redirect-unauthenticated (wrap-secure company-reports/page))
|
||||
:company-reports-table (wrap-client-redirect-unauthenticated (wrap-secure company-reports/table))
|
||||
:company-reports-delete (wrap-client-redirect-unauthenticated (wrap-admin company-reports/delete-report))
|
||||
:transaction-insights (wrap-client-redirect-unauthenticated (wrap-secure insights/page))
|
||||
:transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-secure insights/insight-table))
|
||||
:transaction-insight-rows (wrap-client-redirect-unauthenticated (wrap-secure insights/transaction-rows))
|
||||
:transaction-insight-approve (wrap-client-redirect-unauthenticated (wrap-secure insights/approve))
|
||||
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-secure insights/explain))
|
||||
:transaction-insights (wrap-client-redirect-unauthenticated (wrap-admin insights/page))
|
||||
:transaction-insight-table (wrap-client-redirect-unauthenticated (wrap-admin insights/insight-table))
|
||||
:transaction-insight-rows (wrap-client-redirect-unauthenticated (wrap-admin insights/transaction-rows))
|
||||
:transaction-insight-approve (wrap-client-redirect-unauthenticated (wrap-admin insights/approve))
|
||||
:transaction-insight-explain (wrap-client-redirect-unauthenticated (wrap-admin insights/explain))
|
||||
:admin-ezcater-xls (wrap-client-redirect-unauthenticated (wrap-admin ezcater-xls/page))
|
||||
:search (wrap-client-redirect-unauthenticated (wrap-secure search/dialog-contents))})
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
(defn page [{:keys [identity matched-route session] :as request}]
|
||||
(base-page
|
||||
request
|
||||
(com/page {:nav (com/admin-aside-nav)
|
||||
(com/page {:nav (com/main-aside-nav)
|
||||
:active-client (:client (:session request))
|
||||
:identity (:identity request)
|
||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
|
||||
Reference in New Issue
Block a user