Made admin clients easier to work with.
This commit is contained in:
2414
package-lock.json
generated
2414
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
"react-prop-types": "^0.4.0",
|
||||
"react-signature-canvas": "^1.0.3",
|
||||
"react-signature-pad": "0.0.6",
|
||||
"react-transition-group": "^2.4.0",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"recharts": "^1.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"needs-activation" :needs-activation
|
||||
"payments/" :payments
|
||||
"admin/" {"" :admin
|
||||
"clients" :admin-clients
|
||||
"clients/" {"" :admin-clients
|
||||
[:id] {"" :admin-specific-client
|
||||
"/bank-accounts/" {[:bank-account] :admin-specific-bank-account}}}
|
||||
"users" :admin-users
|
||||
"rules" :admin-rules
|
||||
"accounts" :admin-accounts
|
||||
@@ -29,7 +31,6 @@
|
||||
"unapproved" :unapproved-transactions
|
||||
"approved" :approved-transactions
|
||||
"requires-feedback" :requires-feedback-transactions
|
||||
|
||||
"excluded" :excluded-transactions}
|
||||
"reports/" {"" :reports}
|
||||
"ledger/" {"" :ledger
|
||||
|
||||
@@ -40,27 +40,27 @@
|
||||
(cond
|
||||
(= :login handler)
|
||||
{:db (assoc db/default-db
|
||||
:active-page :login
|
||||
:active-route :login
|
||||
:last-client-id (.getItem js/localStorage "last-client-id")
|
||||
:user nil)}
|
||||
|
||||
(and (not= :login handler) (not token))
|
||||
{:redirect "/login"
|
||||
:db (assoc db/default-db
|
||||
:active-page :login
|
||||
:active-route :login
|
||||
:last-client-id (.getItem js/localStorage "last-client-id")
|
||||
:user token)}
|
||||
|
||||
(and token (= "none" (or (get (jwt->data token) "role") (get (jwt->data token) "user/role")) ))
|
||||
{:redirect "/needs-activation"
|
||||
:db (assoc db/default-db
|
||||
:active-page :needs-activation
|
||||
:active-route :needs-activation
|
||||
:last-client-id (.getItem js/localStorage "last-client-id")
|
||||
:user token)}
|
||||
|
||||
:else
|
||||
{:db (assoc db/default-db
|
||||
:active-page handler
|
||||
:active-route handler
|
||||
:is-initial-loading? true
|
||||
:last-client-id (.getItem js/localStorage "last-client-id")
|
||||
:query-params (auto-ap.views.utils/query-params)
|
||||
@@ -123,7 +123,7 @@
|
||||
(assoc db :initial-error e
|
||||
|
||||
:is-initial-loading? false
|
||||
:active-page :initial-error)))
|
||||
:active-route :initial-error)))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::swap-client
|
||||
@@ -140,20 +140,19 @@
|
||||
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::set-active-page
|
||||
(fn [{:keys [db]} [_ handler params]]
|
||||
::set-active-route
|
||||
(fn [{:keys [db]} [_ handler params route-params]]
|
||||
|
||||
|
||||
(if (and (not= :login handler) (not (:user db)))
|
||||
{:redirect "/login"
|
||||
:db (assoc db :active-page :login
|
||||
:page-failure nil
|
||||
:auto-ap.forms/forms nil)}
|
||||
:db (assoc db :active-route :login
|
||||
:page-failure nil)}
|
||||
{:db (-> db
|
||||
(assoc :active-page handler
|
||||
(assoc :active-route handler
|
||||
:page-failure nil
|
||||
:query-params params
|
||||
:auto-ap.forms/forms nil)
|
||||
:route-params route-params)
|
||||
(auto-ap.views.pages.data-page/dispose-all))})))
|
||||
|
||||
|
||||
|
||||
@@ -105,8 +105,6 @@
|
||||
(re-frame/reg-event-db
|
||||
::save-error
|
||||
(fn [db [_ form result]]
|
||||
(println result)
|
||||
|
||||
(-> db
|
||||
(assoc-in [::forms form :status] :error)
|
||||
(assoc-in [::forms form :error] (or (:message (first result))
|
||||
@@ -153,7 +151,7 @@
|
||||
(assoc-in [::forms id :error] nil)))
|
||||
|
||||
|
||||
(defn vertical-form [{:keys [can-submit id change-event submit-event ]}]
|
||||
(defn vertical-form [{:keys [can-submit id change-event submit-event fullwidth?] :or {fullwidth? true}}]
|
||||
{:form
|
||||
(fn [{:keys [title] :as params} & children]
|
||||
(let [{:keys [data active? error]} @(re-frame/subscribe [::form id])
|
||||
@@ -190,13 +188,15 @@
|
||||
(assoc-in [1 :event] change-event))]))
|
||||
:field-holder (fn [label control]
|
||||
[:div.field
|
||||
(when label [:p.help label])
|
||||
(when label (if fullwidth? [:p.help label]
|
||||
[:label.label label]))
|
||||
[:div.control control]])
|
||||
:field ^{:key "field"}
|
||||
(fn [label control]
|
||||
(let [{:keys [data]} @(re-frame/subscribe [::form id])]
|
||||
[:div.field
|
||||
(when label [:p.help label])
|
||||
(when label (if fullwidth? [:p.help label]
|
||||
[:label.label label]))
|
||||
[:div.control [bind-field (-> control
|
||||
(assoc-in [1 :subscription] data)
|
||||
(assoc-in [1 :event] change-event))]]]))
|
||||
@@ -210,8 +210,9 @@
|
||||
(let [error (:error @(re-frame/subscribe [::form id]))
|
||||
status @(re-frame/subscribe [::status/single id])
|
||||
can-submit @(re-frame/subscribe can-submit)]
|
||||
[:button.button.is-medium.is-primary.is-fullwidth {:disabled (or (status/disabled-for status)
|
||||
[:button.button.is-medium.is-primary {:disabled (or (status/disabled-for status)
|
||||
(not can-submit))
|
||||
:class (status/class-for status) }
|
||||
:class (cond-> (status/class-for status)
|
||||
fullwidth? (conj "is-fullwidth")) }
|
||||
child]))})
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
(defn- dispatch-route [matched-route]
|
||||
(println "Matched route" matched-route)
|
||||
(re-frame/dispatch [:auto-ap.events/set-active-page (:handler matched-route) (u/query-params)]))
|
||||
(re-frame/dispatch [:auto-ap.events/set-active-route (:handler matched-route) (u/query-params) (:route-params matched-route)]))
|
||||
|
||||
|
||||
(def history (pushy/pushy dispatch-route parse-url))
|
||||
|
||||
@@ -139,15 +139,29 @@
|
||||
(js->clj (.parse js/JSON (base64/decodeString (second (str/split (:user db) #"\.")))) :keywordize-keys true))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::active-page
|
||||
::active-route
|
||||
(fn [db]
|
||||
(:active-page db)))
|
||||
(:active-route db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::active-page
|
||||
:<- [::active-route]
|
||||
(fn [route]
|
||||
(or ({:admin-specific-client :admin-clients
|
||||
:admin-specific-bank-account :admin-clients}
|
||||
route)
|
||||
route)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::query-params
|
||||
(fn [db]
|
||||
(:query-params db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::route-params
|
||||
(fn [db]
|
||||
(:route-params db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::page-failure
|
||||
(fn [db]
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
(defmethod page :admin-clients [_]
|
||||
(admin-clients-page))
|
||||
|
||||
(defmethod page :admin-specific-client [_]
|
||||
(admin-clients-page))
|
||||
|
||||
|
||||
(defmethod page :admin-rules [_]
|
||||
(admin-rules-page))
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
(ns auto-ap.views.pages.admin.clients
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.string :as str]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.coerce :as coerce]
|
||||
[auto-ap.subs :as subs]
|
||||
(:require
|
||||
[auto-ap.forms :as forms]
|
||||
[auto-ap.events :as events]
|
||||
[auto-ap.entities.clients :as entity]
|
||||
[auto-ap.views.components.address :refer [address-field]]
|
||||
[auto-ap.views.components.layouts :refer [side-bar-layout appearing-side-bar side-bar] ]
|
||||
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
|
||||
[auto-ap.views.utils :refer [login-url dispatch-event dispatch-value-change bind-field horizontal-field nf with-user]]
|
||||
[auto-ap.views.pages.admin.clients.table :as table]
|
||||
[auto-ap.views.pages.admin.clients.form :as form]
|
||||
[cljs.reader :as edn]
|
||||
[auto-ap.routes :as routes]
|
||||
[bidi.bidi :as bidi]
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.status :as status]
|
||||
[auto-ap.views.components.admin.side-bar :refer [admin-side-bar]]
|
||||
[auto-ap.views.components.grid :as grid]
|
||||
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
||||
[auto-ap.views.pages.admin.clients.form :as form]
|
||||
[auto-ap.views.pages.admin.clients.side-bar :as side-bar]
|
||||
[vimsical.re-frame.fx.track :as track]))
|
||||
[auto-ap.views.pages.admin.clients.table :as table]
|
||||
[auto-ap.views.utils :refer [dispatch-event transition switch-transition with-user transition-group]]
|
||||
[clojure.string :as str]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as r]
|
||||
[vimsical.re-frame.fx.track :as track]
|
||||
[bidi.bidi :as bidi]
|
||||
[auto-ap.routes :as routes]))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::received-intuit-bank-accounts
|
||||
@@ -82,24 +76,130 @@
|
||||
:data (grid/virtual-paginate (:start params) (:per-page params) matching-clients)))))
|
||||
|
||||
|
||||
(defn stacked-page [& children]
|
||||
[:div
|
||||
(->> children
|
||||
(reverse)
|
||||
(filter identity)
|
||||
first)])
|
||||
|
||||
(defn hierachy []
|
||||
(let [last-stack-size (r/atom (->> (r/current-component)
|
||||
r/children
|
||||
(filter identity) count))
|
||||
forward? (r/atom false)]
|
||||
(fn []
|
||||
(let [stack (filter identity (r/children (r/current-component)))
|
||||
current-stack-size (count stack)
|
||||
current-child (last stack)]
|
||||
(when (not= current-stack-size @last-stack-size)
|
||||
(reset! forward? (> current-stack-size @last-stack-size))
|
||||
(reset! last-stack-size current-stack-size))
|
||||
[:div
|
||||
[switch-transition {:mode "in-out"}
|
||||
|
||||
^{:key current-stack-size}
|
||||
[transition
|
||||
{:timeout 100
|
||||
:exit true
|
||||
:in true #_(= current-stack- (:key (meta child)))
|
||||
:appear (> current-stack-size 1)}
|
||||
(clj->js (fn [state]
|
||||
(r/as-element
|
||||
[:div {:style {
|
||||
:position (cond
|
||||
(= "entered" state)
|
||||
""
|
||||
|
||||
(= "entering" state)
|
||||
"absolute"
|
||||
|
||||
(= "exiting" state)
|
||||
"absolute"
|
||||
|
||||
(= "exited" state)
|
||||
"")
|
||||
|
||||
:transition "opacity 300ms ease-in-out, transform 300ms ease-in-out"
|
||||
|
||||
:opacity (cond
|
||||
(= "entered" state)
|
||||
""
|
||||
|
||||
(= "entering" state)
|
||||
0.0
|
||||
|
||||
(= "exiting" state)
|
||||
1.0
|
||||
|
||||
(= "exited" state)
|
||||
0.0)
|
||||
:transform (if @forward?
|
||||
(cond
|
||||
(= "entered" state)
|
||||
""
|
||||
|
||||
(= "entering" state)
|
||||
"translateX(100%)"
|
||||
|
||||
(= "exiting" state)
|
||||
"translateX(-100%)"
|
||||
|
||||
(= "exited" state)
|
||||
"translateX(0%)")
|
||||
(cond
|
||||
(= "entered" state)
|
||||
""
|
||||
|
||||
(= "entering" state)
|
||||
"translateX(-100%)"
|
||||
|
||||
(= "exiting" state)
|
||||
"translateX(100%)"
|
||||
|
||||
(= "exited" state)
|
||||
"translateX(0%)"))}}
|
||||
current-child])))]]
|
||||
]))))
|
||||
|
||||
(defn test-appear []
|
||||
[:div
|
||||
[hierachy
|
||||
[table/clients-table {:page @(re-frame/subscribe [::page])
|
||||
:status @(re-frame/subscribe [::status/single ::page])}]
|
||||
(when (#{:admin-specific-bank-account :admin-specific-client} @(re-frame/subscribe [::subs/active-route]))
|
||||
[form/new-client-form])
|
||||
(when (= :admin-specific-bank-account @(re-frame/subscribe [::subs/active-route]))
|
||||
[:div "This is a bank account!"])]])
|
||||
|
||||
(defn breadcrumbs []
|
||||
[:h1.title.is-1
|
||||
(cond (= :admin-clients @(re-frame/subscribe [::subs/active-route]))
|
||||
"Clients"
|
||||
|
||||
:else
|
||||
[:span [:a {:href (bidi/path-for routes/routes :admin-clients)}
|
||||
"Clients"]
|
||||
" / "
|
||||
(or (:name (:data @(re-frame/subscribe [::forms/form ::form/form])))
|
||||
[:i "New client"])])
|
||||
])
|
||||
(def admin-clients-content
|
||||
(with-meta
|
||||
(fn []
|
||||
[:div
|
||||
[:div
|
||||
[:h1.title "Clients"]
|
||||
[breadcrumbs]
|
||||
[:div.is-pulled-right
|
||||
[:a.button.is-primary.is-outlined {:on-click (dispatch-event [::new])} "New client"]]
|
||||
[table/clients-table {:page @(re-frame/subscribe [::page])
|
||||
:status @(re-frame/subscribe [::status/single ::page])}]]])
|
||||
(when (= :admin-clients @(re-frame/subscribe [::subs/active-route]))
|
||||
[:a.button.is-primary.is-outlined {:href (bidi/path-for routes/routes :admin-specific-client :id "new")} "New client"])]
|
||||
[test-appear]
|
||||
])
|
||||
{:component-did-mount #(re-frame/dispatch [::mounted])
|
||||
:component-will-unmount #(re-frame/dispatch-sync [::unmounted])}))
|
||||
|
||||
|
||||
(defn admin-clients-page []
|
||||
(let [{:keys [active?]} @(re-frame/subscribe [::forms/form ::form/form])]
|
||||
[side-bar-layout {:side-bar [admin-side-bar {}
|
||||
[side-bar/client-side-bar]]
|
||||
:main [admin-clients-content]
|
||||
:right-side-bar [appearing-side-bar {:visible? active?} [form/new-client-form]] }]))
|
||||
:main [admin-clients-content]}])
|
||||
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
[cljs-time.coerce :as coerce]
|
||||
[cljs-time.core :as t]
|
||||
[clojure.string :as str]
|
||||
[vimsical.re-frame.cofx.inject :as inject]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as r]
|
||||
[react-signature-canvas]))
|
||||
[react-signature-canvas]
|
||||
[bidi.bidi :as bidi]
|
||||
[auto-ap.routes :as routes]))
|
||||
|
||||
(def signature-canvas (r/adapt-react-class (.-default react-signature-canvas)))
|
||||
|
||||
@@ -54,8 +57,8 @@
|
||||
[:div
|
||||
[signature-canvas {"canvasProps" {"width" w
|
||||
"height" h
|
||||
"style" #js {"border" "1px solid rgb(219,219,219)"
|
||||
"border-radius" "4px"}}
|
||||
"style" #js {"border" "1px solid #CCC"
|
||||
"border-radius" "10px"}}
|
||||
"backgroundColor" "#FFF"
|
||||
:ref (fn [el]
|
||||
(reset! canvas el))}]
|
||||
@@ -72,7 +75,9 @@
|
||||
[:div
|
||||
[:img {:src (or signature-data signature-file)
|
||||
:style {:width w
|
||||
:height h}}]
|
||||
:height h
|
||||
:border "1px solid #CCC"
|
||||
:border-radius "10px"}}]
|
||||
[:div.buttons
|
||||
[:a.button {:on-click (fn []
|
||||
(reset! edit-mode? true))}
|
||||
@@ -83,7 +88,10 @@
|
||||
[:div.has-text-centered.is-vcentered {:style {:width w
|
||||
:height h
|
||||
:margin-bottom "8px"
|
||||
:background "#EEE"}}
|
||||
:border "1px solid #CCC"
|
||||
:border-radius "10px"
|
||||
:background "#EEE"
|
||||
}}
|
||||
"No signature"]
|
||||
[:div.buttons
|
||||
[:a.button.is-primary.is-outlined {:on-click (fn []
|
||||
@@ -113,9 +121,9 @@
|
||||
:square-auth-token (:square-auth-token new-client-data)
|
||||
:square-locations (map
|
||||
(fn [x]
|
||||
{:id (:id x)
|
||||
{:id (:id (:square-location x))
|
||||
:client-location (:client-location x)})
|
||||
(:square-locations new-client-data))
|
||||
(:selected-square-locations new-client-data))
|
||||
|
||||
:ezcater-locations (map
|
||||
(fn [x]
|
||||
@@ -189,11 +197,21 @@
|
||||
(:bank-accounts new-client-data))})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::editing
|
||||
(fn [{:keys [db]} [_ client-id]]
|
||||
::mounted
|
||||
[(re-frame/inject-cofx ::inject/sub [::subs/route-params])
|
||||
(re-frame/inject-cofx ::inject/sub [::subs/clients-by-id])]
|
||||
(fn [{:keys [db]
|
||||
::subs/keys [clients-by-id route-params]} [_ client-id]]
|
||||
(let [client (get clients-by-id (:id route-params))]
|
||||
{:db (-> db
|
||||
(forms/stop-form ::form)
|
||||
(forms/start-form ::form (-> (get (:clients db) client-id)
|
||||
(forms/start-form ::form (-> client
|
||||
(assoc :selected-square-locations (->> (:square-locations client)
|
||||
(filter :client-location )
|
||||
(mapv (fn [sl]
|
||||
{:id (:id sl)
|
||||
:square-location sl
|
||||
:client-location (:client-location sl)}))))
|
||||
(update :locations #(mapv (fn [l] {:location l}) %))
|
||||
(update :matches #(mapv (fn [l] {:match l}) %))
|
||||
(update :bank-accounts
|
||||
@@ -202,7 +220,7 @@
|
||||
(update ba :locations (fn [ls]
|
||||
(map (fn [l] {:location l})
|
||||
ls))))
|
||||
bas))))))}))
|
||||
bas))))))})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::save-new-client
|
||||
@@ -222,13 +240,16 @@
|
||||
(events/client-query user)]}]}
|
||||
:on-success [::save-complete]
|
||||
:on-error [::forms/save-error ::form]}})))
|
||||
(re-frame/reg-event-db
|
||||
::save-complete
|
||||
(fn [db [_ client]]
|
||||
(-> db
|
||||
(forms/stop-form ::form)
|
||||
|
||||
(assoc-in [:clients (:id (:edit-client client))] (update (:edit-client client) :bank-accounts (fn [bas] (->> bas (sort-by :sort-order) vec)))))))
|
||||
(re-frame/reg-event-fx
|
||||
::save-complete
|
||||
(fn [{:keys [db]} [_ client]]
|
||||
{:db
|
||||
(-> db
|
||||
#_(forms/stop-form ::form)
|
||||
|
||||
(assoc-in [:clients (:id (:edit-client client))] (update (:edit-client client) :bank-accounts (fn [bas] (->> bas (sort-by :sort-order) vec)))))
|
||||
:redirect (bidi/path-for routes/routes :admin-clients)}))
|
||||
|
||||
|
||||
|
||||
@@ -285,7 +306,8 @@
|
||||
(forms/vertical-form {:can-submit [::can-submit]
|
||||
:change-event [::forms/change ::form]
|
||||
:submit-event [::save-new-client ]
|
||||
:id ::form}))
|
||||
:id ::form
|
||||
:fullwidth? false}))
|
||||
|
||||
(def first-week-a (coerce/to-date-time #inst "1999-12-27T00:00:00.000-07:00"))
|
||||
|
||||
@@ -314,8 +336,9 @@
|
||||
|
||||
(defn bank-account-card [new-client {:keys [active? new? type visible code name sort-order]} first? last?]
|
||||
(let [{:keys [field raw-field]} client-form]
|
||||
[:div.card {:style {:margin-bottom "1em"}}
|
||||
[:header.card-header
|
||||
[:div.card {:style {:margin-bottom "1em"
|
||||
:width "600px"}}
|
||||
[:header.card-header.has-background-primary-light
|
||||
[:div.card-header-title {:style {:text-overflow "ellipsis"}}
|
||||
[:div.level {:style {:width "100%"}}
|
||||
[:div.level-left
|
||||
@@ -327,6 +350,8 @@
|
||||
(#{:credit ":credit"} type) [:span.icon-credit-card-1]
|
||||
|
||||
:else [:span.icon-accounting-bill])]]
|
||||
#_[:div.level-item
|
||||
]
|
||||
[:div.level-item code ": " name]]
|
||||
[:div.level-right
|
||||
[:div.level-item
|
||||
@@ -373,7 +398,7 @@
|
||||
:field [:bank-accounts sort-order :name]}]]
|
||||
[horizontal-field
|
||||
nil
|
||||
[field "Numeric Code (for finiancials)"
|
||||
[field "Numeric Code"
|
||||
[:input.input {:placeholder "20101"
|
||||
:type "text"
|
||||
:field [:bank-accounts sort-order :numeric-code]}]]]
|
||||
@@ -399,6 +424,7 @@
|
||||
:field [:bank-accounts sort-order :bank-name]}]]
|
||||
[field "Routing #"
|
||||
[:input.input {:placeholder "104819123"
|
||||
:style {:width "9em"}
|
||||
:type "text"
|
||||
:field [:bank-accounts sort-order :routing]}]]
|
||||
[field "Bank code"
|
||||
@@ -406,16 +432,17 @@
|
||||
:type "text"
|
||||
:field [:bank-accounts sort-order :bank-code]}]]]
|
||||
|
||||
[:label.label "Checking account"]
|
||||
[horizontal-field
|
||||
nil
|
||||
[field "Account #"
|
||||
[:input.input {:placeholder "123456789"
|
||||
:type "text"
|
||||
:style {:width "20em"}
|
||||
:field [:bank-accounts sort-order :number]}]]
|
||||
|
||||
[field "Check Number"
|
||||
[:input.input {:placeholder "10000"
|
||||
:style {:width "6em"}
|
||||
:type "text"
|
||||
:field [:bank-accounts sort-order :check-number]}]]]
|
||||
[field "Yodlee Account"
|
||||
@@ -520,8 +547,15 @@
|
||||
(when new?
|
||||
[:a.card-footer-item.is-warning {:href "#" :on-click (dispatch-event [::bank-account-removed sort-order])} "Remove"])])]))
|
||||
|
||||
(defn new-client-form []
|
||||
(let [{new-client :data } @(re-frame/subscribe [::forms/form ::form])
|
||||
(defn form-section [{:keys [title]}]
|
||||
[:<>
|
||||
[:h4.is-4.title title]
|
||||
[:hr]
|
||||
(into [:div {:style {:margin-bottom "5em"}}]
|
||||
(r/children (r/current-component)))])
|
||||
|
||||
(defn form-content []
|
||||
(let [{new-client :data :as f} @(re-frame/subscribe [::forms/form ::form])
|
||||
{:keys [form-inline field raw-field error-notification submit-button ]} client-form
|
||||
next-week-a (if (is-week-a? (t/now))
|
||||
"This week"
|
||||
@@ -529,29 +563,60 @@
|
||||
next-week-b (if (is-week-a? (t/now))
|
||||
"Next week"
|
||||
"This week")]
|
||||
[side-bar {:on-close (dispatch-event [::forms/form-closing ::form ])}
|
||||
^{:key (:id new-client)}
|
||||
^{:key (or (:id new-client)
|
||||
"new")}
|
||||
[:div ;; div is important for actually unmounting for now
|
||||
(form-inline {:title "Add client"}
|
||||
|
||||
|
||||
(form-inline {:title ""}
|
||||
[:<>
|
||||
|
||||
|
||||
[form-section {:title "General"}
|
||||
(field "Name"
|
||||
[:input.input {:type "text"
|
||||
:style {:width "20em"}
|
||||
:field [:name]
|
||||
:spec ::entity/name
|
||||
}])
|
||||
|
||||
|
||||
[:div.field
|
||||
[:p.help "Client code"
|
||||
]
|
||||
[:label.label "Client code"]
|
||||
(if (:id new-client)
|
||||
[:div.control
|
||||
(:code new-client)]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[:input.input {:type "code"
|
||||
:style {:width "5em"}
|
||||
:field :code
|
||||
:spec ::entity/code
|
||||
:disabled true}])
|
||||
]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[:input.input {:type "code"
|
||||
:style {:width "5em"}
|
||||
:field :code
|
||||
:spec ::entity/code}])])]
|
||||
|
||||
[:div.field
|
||||
[:label.label "Locations"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
:field :locations
|
||||
:allow-change? false
|
||||
:template [[:input.input {:field [:location]
|
||||
:maxlength 2
|
||||
:style { :width "4em"}}]]}])]]
|
||||
|
||||
[:div.field
|
||||
[:label.label "Signature"]
|
||||
[signature {:signature-file (:signature-file new-client)
|
||||
:signature-data (:signature-data new-client)
|
||||
:on-change (fn [uri]
|
||||
(re-frame/dispatch [::forms/change ::form [:signature-data] uri]))}]]
|
||||
|
||||
|
||||
|
||||
(field "Locked Until"
|
||||
[date-picker {:class-name "input"
|
||||
:class "input"
|
||||
@@ -561,10 +626,13 @@
|
||||
:next-month-button-label ""
|
||||
:next-month-label ""
|
||||
:type "date"
|
||||
:field [:locked-until]}])
|
||||
:field [:locked-until]
|
||||
:style {:width "15em"}}])]
|
||||
|
||||
[form-section {:title "Contacts"}
|
||||
|
||||
[:h2.subtitle.is-5 "Emails (address/description)"]
|
||||
[:div.field
|
||||
[:label.label "Emails (address/description)"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
@@ -575,36 +643,28 @@
|
||||
:spec ::entity/email}]
|
||||
[:input.input {:type "text"
|
||||
:placeholder "Manager"
|
||||
:field [:description]}]]}])]
|
||||
:field [:description]}]]}])]]
|
||||
[:label.label "Address"]
|
||||
[:div {:style {:width "30em"}}
|
||||
[address-field {:field [:address]
|
||||
:event [::forms/change ::form]
|
||||
:subscription new-client}]]]
|
||||
|
||||
|
||||
[form-section {:title "Matching"}
|
||||
[:div.field
|
||||
[:p.help "Signature"]
|
||||
[signature {:signature-file (:signature-file new-client)
|
||||
:signature-data (:signature-data new-client)
|
||||
:on-change (fn [uri]
|
||||
(re-frame/dispatch [::forms/change ::form [:signature-data] uri]))}]]
|
||||
|
||||
[:h2.subtitle.is-5 "Name matches"]
|
||||
[:label.label "Name matches"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
:field :matches
|
||||
:template [[:input.input {:field [:match]
|
||||
:placeholder "Harry's burger joint"
|
||||
:style { :width "15em"}}]]}])]
|
||||
:style { :width "15em"}}]]}])]]
|
||||
|
||||
|
||||
[:h2.subtitle "Locations"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
:field :locations
|
||||
:allow-change? false
|
||||
:template [[:input.input {:field [:location]
|
||||
:maxlength 2
|
||||
:style { :width "4em"}}]]}])]
|
||||
|
||||
[:h2.subtitle "Location Matches"]
|
||||
[:div.field
|
||||
[:label.label "Location Matches"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
@@ -615,50 +675,56 @@
|
||||
[:input.input {:field [:location]
|
||||
:placeholder "DT"
|
||||
:maxlength 2
|
||||
:style { :width "4em"}}]]}])]
|
||||
|
||||
[:h2.subtitle "Address"]
|
||||
[address-field {:field [:address]
|
||||
:event [::forms/change ::form]
|
||||
:subscription new-client}]
|
||||
:style { :width "4em"}}]]}])]]]
|
||||
|
||||
|
||||
[:h2.subtitle "Bank accounts"]
|
||||
|
||||
|
||||
[form-section {:title "Bank Accounts"}
|
||||
(for [bank-account (sort-by :sort-order (:bank-accounts new-client))]
|
||||
^{:key (:sort-order bank-account)}
|
||||
[bank-account-card new-client bank-account (= 0 (:sort-order bank-account)) (= (:sort-order bank-account) (dec (count (:bank-accounts new-client))))])
|
||||
|
||||
[:div.columns
|
||||
[:div.column.is-third
|
||||
[:a.button.is-primary.is-outlined.is-fullwidth {:on-click (dispatch-event [::add-new-bank-account :credit])} "Add Credit Account"]]
|
||||
[:div.column.is-third
|
||||
[:a.button.is-primary.is-outlined.is-fullwidth {:on-click (dispatch-event [::add-new-bank-account :check])} "Add Checking Account"]]
|
||||
[:div.column.is-third
|
||||
[:a.button.is-primary.is-outlined.is-fullwidth {:on-click (dispatch-event [::add-new-bank-account :cash])} "Add Cash Account"]]]
|
||||
[:div.buttons
|
||||
[:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :credit])} "Add Credit Account"]
|
||||
[:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :check])} "Add Checking Account"]
|
||||
[:a.button.is-primary.is-outlined {:on-click (dispatch-event [::add-new-bank-account :cash])} "Add Cash Account"]]]
|
||||
|
||||
[:h2.subtitle "Cash flow"]
|
||||
[form-section {:title "Cash flow"}
|
||||
[:label.label (str "Week A (" next-week-a ")")]
|
||||
[:div.level
|
||||
[:div.level-left
|
||||
[:div.level-item
|
||||
[field "Regular Credits"
|
||||
[:input.input {:type "number"
|
||||
:style {:width "10em"}
|
||||
:placeholder "500.00"
|
||||
:field [:week-a-credits]
|
||||
:step "0.01"}]]
|
||||
:step "0.01"}]]]
|
||||
[:div.level-item
|
||||
[field "Regular Debits"
|
||||
[:input.input {:type "number"
|
||||
:style {:width "10em"}
|
||||
:placeholder "150.00"
|
||||
:field [:week-a-debits]
|
||||
:step "0.01"}]]
|
||||
:step "0.01"}]]]]]
|
||||
[:label.label (str "Week B (" next-week-b ")")]
|
||||
[:div.level
|
||||
[:div.level-left
|
||||
[:div.level-item
|
||||
[field "Regular Credits"
|
||||
[:input.input {:type "number"
|
||||
:style {:width "10em"}
|
||||
:placeholder "1000.00"
|
||||
:field [:week-b-credits]
|
||||
:step "0.01"}]]
|
||||
:step "0.01"}]]]
|
||||
[:div.level-item
|
||||
[field "Regular Debits"
|
||||
[:input.input {:type "number"
|
||||
:style {:width "10em"}
|
||||
:placeholder "250.00"
|
||||
:field [:week-b-debits]
|
||||
:step "0.01"}]]
|
||||
:step "0.01"}]]]]]
|
||||
[:div.field
|
||||
[:label.label "Forecasted transactions"]
|
||||
|
||||
@@ -671,8 +737,8 @@
|
||||
:style {:width "10em"}
|
||||
:field [ :identifier]}]
|
||||
[:input.input {:type "number"
|
||||
:style {:width "4em"}
|
||||
:placeholder "Day of month"
|
||||
:style {:width "8em"}
|
||||
:placeholder "DOM"
|
||||
:step "1"
|
||||
:field [:day-of-month]}]
|
||||
[:input.input {:type "number"
|
||||
@@ -680,26 +746,31 @@
|
||||
:class "has-text-right"
|
||||
:style {:width "7em"}
|
||||
:field [:amount]
|
||||
:step "0.01"}]]}])]]
|
||||
:step "0.01"}]]}])]]]
|
||||
|
||||
[form-section {:title "Square Integration"}
|
||||
(field "Square Authentication Token"
|
||||
[:input.input {:type "text"
|
||||
:style {:width "40em"}
|
||||
:field [:square-auth-token]}])
|
||||
[:div.field
|
||||
[:label.label "Square Locations"]
|
||||
[:div.control
|
||||
(raw-field
|
||||
[multi-field {:type "multi-field"
|
||||
:field :square-locations
|
||||
:template [[:input.input {:type "text"
|
||||
:field :selected-square-locations
|
||||
:template [[typeahead-v3 {:entities (:square-locations new-client)
|
||||
:entity->text :name
|
||||
:type "typeahead-v3"
|
||||
:style {:width "15em"}
|
||||
:disabled true
|
||||
:field [:name]}]
|
||||
:field [:square-location]}]
|
||||
[:input.input {:type "text"
|
||||
:style {:width "4em"}
|
||||
:field [:client-location]
|
||||
:step "0.01"}]]
|
||||
:disable-remove? true
|
||||
:disable-new? true}])]]
|
||||
:disable-remove? true}])]]]
|
||||
|
||||
[form-section {:title "EZCater integration"}
|
||||
|
||||
[:div.field
|
||||
[:label.label "EZCater Locations"]
|
||||
@@ -720,7 +791,13 @@
|
||||
:style {:width "4em"}
|
||||
:field [:location]
|
||||
:step "0.01"}]]
|
||||
:disable-remove? true}])]]
|
||||
:disable-remove? true}])]]]
|
||||
|
||||
(error-notification)
|
||||
(submit-button "Save")])]]))
|
||||
(submit-button "Save")])]))
|
||||
|
||||
(def new-client-form
|
||||
(with-meta
|
||||
(fn []
|
||||
[form-content])
|
||||
{:component-did-mount #(re-frame/dispatch [::mounted])}))
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
(:require [auto-ap.subs :as subs]
|
||||
[clojure.string :as str]
|
||||
[re-frame.core :as re-frame]
|
||||
[auto-ap.views.pages.admin.clients.form :as form]
|
||||
[auto-ap.views.utils :refer [action-cell-width date->str with-user]]
|
||||
[auto-ap.views.components.grid :as grid]
|
||||
[auto-ap.views.components.modal :as modal]
|
||||
[auto-ap.views.components.buttons :as buttons]
|
||||
[auto-ap.status :as status]))
|
||||
[auto-ap.status :as status]
|
||||
[bidi.bidi :as bidi]
|
||||
[auto-ap.routes :as routes]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::specific-params
|
||||
@@ -115,5 +116,5 @@
|
||||
[grid/cell {} [:div.buttons [buttons/fa-icon {:event [::setup-sales-queries id]
|
||||
:class (status/class-for (get states id))
|
||||
:icon :fa-dollar}]
|
||||
[buttons/fa-icon {:event [::form/editing id]
|
||||
[buttons/fa-icon {:href (bidi/path-for routes/routes :admin-specific-client :id id)
|
||||
:icon :fa-pencil}]]]])]]]))
|
||||
|
||||
@@ -118,6 +118,14 @@
|
||||
(def css-transition-group
|
||||
(reagent/adapt-react-class react-transition-group/CSSTransition))
|
||||
|
||||
(def transition
|
||||
(reagent/adapt-react-class react-transition-group/Transition))
|
||||
|
||||
(def transition-group
|
||||
(reagent/adapt-react-class react-transition-group/TransitionGroup))
|
||||
|
||||
(def switch-transition
|
||||
(reagent/adapt-react-class react-transition-group/SwitchTransition))
|
||||
|
||||
(defn appearing [{:keys [visible? enter-class exit-class timeout]}]
|
||||
(let [final-state (reagent/atom visible?)]
|
||||
@@ -140,7 +148,7 @@
|
||||
value
|
||||
(conj value {:key (random-uuid)
|
||||
:new? true}))]
|
||||
[:div
|
||||
[:div {:style {:margin-bottom "1em"}}
|
||||
(for [[i override] (map vector (range) value)
|
||||
:let [is-disabled? (if (= false allow-change?)
|
||||
(not (boolean (:new? override)))
|
||||
@@ -148,7 +156,10 @@
|
||||
]
|
||||
^{:key (:key override)}
|
||||
[:div.level
|
||||
[:div.level-left
|
||||
[:div.level-left {:style (when (and (= i (dec (count value)))
|
||||
(:new? override))
|
||||
{:background "#EEE"
|
||||
:padding "0.25em 1em 0.25em 0em"})}
|
||||
[:div.level-item
|
||||
(if (:new? override)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user