(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.pages.company.side-bar :refer [company-side-bar]] [auto-ap.views.components.grid :as grid] [auto-ap.views.components.layouts :refer [side-bar-layout]] [auto-ap.views.pages.admin.plaid.table :as table] [auto-ap.views.utils :refer [dispatch-event with-user]] [re-frame.core :as re-frame] [react-plaid-link :refer [usePlaidLink]] [reagent.core :as reagent] [auto-ap.views.pages.data-page :as data-page] [clojure.set :as set] [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-sub ::plaid-items (fn [db] (::plaid-items db))) (re-frame/reg-event-fx ::params-change (fn [_ [_ params]] {:set-uri-params params})) (re-frame/reg-event-fx ::data-requested (fn [{:keys [db]} [_ params]] (println "PRAAMS" 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 [[_ query-result]] [::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 [{:keys [db]} _] {::forward/dispose {:id ::plaid-item-deleted}})) (re-frame/reg-event-fx ::get-link-token [with-user] (fn [{:keys [db]} [_ client]] {: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)))))) (re-frame/reg-event-db ::received (fn [db [_ d]] (assoc-in db [::plaid-items] (:plaid-item-page d)))) (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]}])}))