(ns auto-ap.views.pages.home (:require [auto-ap.views.components.layouts :refer [side-bar-layout]] [re-frame.core :as re-frame] [auto-ap.subs :as subs] [reagent.core :as r])) (def pie-chart (r/adapt-react-class js/Recharts.PieChart)) (def pie (r/adapt-react-class js/Recharts.Pie)) (def bar-chart (r/adapt-react-class js/Recharts.BarChart)) (def x-axis (r/adapt-react-class js/Recharts.XAxis)) (def y-axis (r/adapt-react-class js/Recharts.YAxis)) (def bar (r/adapt-react-class js/Recharts.Bar)) (def legend (r/adapt-react-class js/Recharts.Legend)) (def cell (r/adapt-react-class js/Recharts.Cell)) (def tool-tip (r/adapt-react-class js/Recharts.Tooltip)) (def colors ["hsl(171, 100%, 41%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"]) (def light-colors ["hsl(171, 60%, 80%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"]) (defn make-pie-chart [{:keys [width height data]}] [pie-chart {:width width :height height} [pie {:fill "#82ca9d" :data data :dataKey "value" :inner-radius 20} (map (fn [x y] ^{:key y} [cell {:key y :fill (colors y)}]) data (range)) ] [tool-tip] [legend]]) (defn make-bar-chart [{:keys [width height data]}] [bar-chart {:width width :height height :data data :fill "#FFFFFF"} [tool-tip] [bar {:dataKey "paid" :fill (get colors 0) :stackId "a" :name "Paid"}] [bar {:dataKey "unpaid" :fill (get light-colors 0) :stackId "a" :name "Unpaid"}] [x-axis {:dataKey "name"}] [y-axis] [legend]] ) (re-frame/reg-event-db ::received (fn [db [_ {:keys [expense-account-stats invoice-stats]}]] (let [expense-account-stats (->> expense-account-stats (map #(update % :total (fn [t] (js/parseFloat t)))) (sort-by :total) (reverse) (take 5)) top-5 (vec (take 5 expense-account-stats)) rest (drop 5 expense-account-stats) other {:account {:id 0 :name "Other"} :total (reduce + 0 (map :total rest))}] (cond-> db (seq top-5) (assoc ::top-expense-categories (conj top-5 other)) (seq invoice-stats) (assoc ::invoice-stats invoice-stats))))) (re-frame/reg-sub ::invoice-stats (fn [db] (println (::invoice-stats db)) (::invoice-stats db))) (re-frame/reg-sub ::top-expense-categories (fn [db] (::top-expense-categories db))) (re-frame/reg-event-fx ::mounted (fn [{:keys [db]} _] {:db (assoc db ::top-expense-categories nil) :graphql {:token (-> db :user) :query-obj {:venia/queries [[:expense_account_stats {:client-id (:id @(re-frame/subscribe [::subs/client]))} [[:account [:id :name]] :total]] [:invoice_stats {:client-id (:id @(re-frame/subscribe [::subs/client]))} [:name :paid :unpaid]]]} :on-success [::received]}})) (defn home-content [] (let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)] ^{:key client-id} [side-bar-layout {:side-bar [:div] :main [:div [:h1.title "Home"] [:h1.title.is-4 "Top expense categories"] (let [expense-categories @(re-frame/subscribe [::top-expense-categories])] (make-pie-chart {:width 800 :height 500 :data (clj->js (map (fn [x] {:name (:name (:account x)) :value (:total x)}) expense-categories))})) [:h1.title.is-4 "Upcoming Bills"] (make-bar-chart {:width 800 :height 500 :data (clj->js @(re-frame/subscribe [::invoice-stats]))})]}])) (defn home-page [] (let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)] (re-frame/dispatch [::mounted]) ^{:key client-id} [home-content]))