Makes plaid user configurable

This commit is contained in:
Bryce
2023-07-24 20:55:40 -07:00
parent 445375d15e
commit 5b5b15cb27
15 changed files with 212 additions and 422 deletions

View File

@@ -31,7 +31,6 @@
[auto-ap.views.pages.admin.users :refer [admin-users-page]]
[auto-ap.views.pages.admin.import-batches :refer [import-batches-page]]
[auto-ap.views.pages.company.yodlee2 :as yodlee2]
[auto-ap.views.pages.company.plaid :as plaid]
[auto-ap.views.pages.company.other :as company-other]))
(defmulti page (fn [active-page] active-page))
@@ -128,9 +127,6 @@
(defmethod page :company-other [_]
(company-other/company-other-page))
(defmethod page :plaid [_]
(plaid/plaid-page))
(defmethod page :admin-accounts [_]
(admin-accounts-page))

View File

@@ -1,83 +0,0 @@
(ns auto-ap.views.pages.admin.plaid.table
(:require
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.buttons :as buttons]
[auto-ap.views.components.grid :as grid]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.pages.data-page :as data-page]
[auto-ap.views.utils
:refer [->$ action-cell-width date->str dispatch-event with-user]]
[re-frame.core :as re-frame]))
(re-frame/reg-event-fx
::plaid-item-deleted
(fn [_ _]
{:dispatch [::modal/modal-closed ]}))
(re-frame/reg-event-fx
::delete-plaid-item
[with-user ]
(fn [{:keys [user]} [_ id ]]
{:graphql {:token user
:owns-state {:single ::delete-plaid-item}
:query-obj
{:venia/operation {:operation/type :mutation
:operation/name "DeletePlaidItem"}
:venia/queries [{:query/data
[:delete-plaid-item
{:id id}
[:message]]}]}
:on-success [::plaid-item-deleted]}}))
(re-frame/reg-event-fx
::delete-requested
[with-user]
(fn [_ [_ id]]
{:dispatch
[::modal/modal-requested {:title "Delete Provider account "
:body [:div "Are you sure you want to delete " id "?"]
:confirm {:value "Delete plaid accounts"
:status-from [::status/single ::delete-plaid-item]
:class "is-danger"
:on-click (dispatch-event [::delete-plaid-item id])
:close-event [::status/completed ::delete-plaid-item]}
:cancel? true}]}))
(re-frame/reg-sub
::params
(fn [db]
(-> db ::params)))
(defn table [{:keys [data-page]}]
(let [{:keys [data]} @(re-frame/subscribe [::data-page/page data-page])
is-admin? @(re-frame/subscribe [::subs/is-admin?])]
[grid/grid {:data-page data-page
:column-count 5}
[grid/controls data]
[grid/table {:fullwidth true}
[grid/header
[grid/row {}
[grid/header-cell {:style {:width "18em"}} "Provider Account"]
[grid/header-cell {:style {:width "12em"}} "Status"]
[grid/header-cell {:style {:width "12em"}} "Last Updated"]
[grid/header-cell {} "Accounts"]
[grid/header-cell {:style {:width (action-cell-width 1)}}]]]
[grid/body
(for [{:keys [id name accounts status last-updated] :as c} (:data data)]
^{:key (str name "-" id)}
[grid/row {:class (:class c) :id id}
[grid/cell {} id]
[grid/cell {} status]
[grid/cell {} (date->str last-updated)]
[grid/cell {}
[:ul
(for [a accounts]
^{:key (:id a)}
[:li (:name a) [:div.tag (->$ (:balance a))]])]]
[grid/cell {}
[:div.buttons
(when is-admin?
[buttons/fa-icon {:event [::delete-requested (:id c)]
:icon "fa-times"}])]]])]]
[grid/bottom-paginator data]]))

View File

@@ -1,176 +0,0 @@
(ns auto-ap.views.pages.company.plaid
(:require
[auto-ap.effects.forward :as forward]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.pages.admin.plaid.table :as table]
[auto-ap.shared-views.company.sidebar :refer [company-side-bar]]
[auto-ap.views.pages.data-page :as data-page]
[auto-ap.views.utils :refer [dispatch-event with-user]]
[clojure.set :as set]
[re-frame.core :as re-frame]
[react-plaid-link :refer [usePlaidLink]]
[reagent.core :as reagent]
[vimsical.re-frame.fx.track :as track]))
(re-frame/reg-sub
::link-token
(fn [db]
(-> db ::link-token)))
(re-frame/reg-sub
::message
(fn [db]
(-> db ::message)))
(re-frame/reg-sub
::params
:<- [::table/params]
(fn [table-params]
table-params))
(re-frame/reg-event-fx
::data-requested
(fn [{:keys [db]} [_ params]]
{:graphql {:token (:user db)
:owns-state {:single ::page}
:query-obj {:venia/queries [{:query/data [:plaid-item-page {:client-id (:id @(re-frame/subscribe [::subs/client]))
:sort (:sort params)
:start (:start params 0)}
[[:plaid-items [:id :last-updated :status
[:client [:id]]
[:accounts [:id :name :number :balance]]]]
:count
:start
:end
:total]]
:query/alias :result}]
}
:on-success (fn [result]
[::data-page/received ::page
(set/rename-keys (:result result)
{:plaid-items :data})])}}))
(re-frame/reg-event-fx
::mounted
(fn [{:keys [db]} _]
{:dispatch [::data-requested]
::forward/register {:id ::plaid-item-deleted
:events #{::table/plaid-item-deleted}
:event-fn (fn [[_ _]]
[::data-requested])}
::track/register {:id ::params
:subscription [::data-page/params ::page]
:event-fn (fn [params]
[::data-requested params])}
:db (dissoc db
::link-token
::message)}))
(re-frame/reg-event-fx
::unmounted
(fn [_ _]
{::forward/dispose {:id ::plaid-item-deleted}
::track/dispose [{:id ::params}]}))
(re-frame/reg-event-fx
::get-link-token
[with-user]
(fn [{:keys [db]} [_ _]]
{:graphql {:token (:user db)
:owns-state {:single ::get-link-token}
:query-obj {:venia/queries [[:plaid-link-token {:client-id (:id @(re-frame/subscribe [::subs/client]))}
[:token]]]}
:on-success [::authenticated]}}))
(re-frame/reg-event-fx
::plaid-linked
(fn [{:keys [db]} [_ m]]
{:db (assoc db ::message (:message (:link-plaid m)))
:dispatch [::data-requested]}))
(re-frame/reg-event-fx
::exchange-token
[with-user]
(fn [{:keys [db]} [_ client public-token]]
{:graphql {:token (:user db)
:owns-state {:single ::get-link-token}
:query-obj
{:venia/operation {:operation/type :mutation
:operation/name "LinkPlaid"}
:venia/queries [{:query/data
[:link-plaid
{:client-code client
:public-token public-token}
[:message]]}]}
:on-success [::plaid-linked]}}))
(re-frame/reg-event-db
::authenticated
(fn [db [_ link-token]]
(-> db
(assoc-in [::link-token] (:token (:plaid-link-token link-token))))))
(defn plaid-item-table []
[table/table {:data-page ::page
:status @(re-frame/subscribe [::status/single ::page])}])
(defn link-button [{:keys [link-token client-code]}]
(let [plaid (usePlaidLink #js {:token link-token
:onSuccess (fn [x]
(re-frame/dispatch [::exchange-token client-code x]))})]
[:div
[:button.button.is-primary {:on-click (.-open plaid)}
[:span [:span.icon [:i.fa.fa-external-link]] " Go to plaid"]]]))
(defn plaid-link-token-button []
(let [status @(re-frame/subscribe [::status/single ::get-link-token])
client @(re-frame/subscribe [::subs/client])]
[:button.button.is-primary {:disabled (status/disabled-for status)
:class (status/class-for status)
:on-click (dispatch-event [::get-link-token (:code client)])}
"Authenticate with Plaid (" (:name client) ")"]))
(defn link-flow []
[:div
(let [link-token @(re-frame/subscribe [::link-token])
client-code (:code @(re-frame/subscribe [::subs/client]))]
(cond
(and link-token client-code)
[:div
"Authentication successful!"
[:f> link-button {:link-token link-token
:client-code client-code}]]
client-code
[plaid-link-token-button]
:else
nil))])
(defn admin-plaid-item-content []
(let [message @(re-frame/subscribe [::message])]
[:div
[:h1.title "Plaid Accounts"]
(when message
[:div.notification.is-info.is-light
message])
[plaid-item-table]
[link-flow]
]))
(defn plaid-page []
(reagent/create-class
{:component-will-unmount #(re-frame/dispatch [::unmounted])
:component-did-mount #(re-frame/dispatch [::mounted])
:reagent-render (fn []
[side-bar-layout {:side-bar [company-side-bar {}]
:main [admin-plaid-item-content]}])}))