Now a simple re-frame app

This commit is contained in:
Bryce Covert
2017-12-07 11:23:57 -08:00
parent 275119c362
commit 5b578c11e8
13 changed files with 618 additions and 40 deletions

View File

@@ -9,15 +9,18 @@
[ring.middleware.json :refer [wrap-json-response]]))
(defroutes app-routes
(GET "/hi" [] "hello")
(GET "/" [] (response/resource-response "index.html" {:root "public"}))
(POST "/pdf-upload"
{{ files "file"} :params :as params}
(let [{:keys [filename tempfile]} (second files)]
(io/copy tempfile (io/file "resources" "public" filename))
(for [{:keys [total date invoice-number customer-identifier]} (parse/parse-file (str "resources/public/" filename))]
(do
(println (str "An invoice #" invoice-number " on " date " for " total))
(str "An invoice for customer " customer-identifier " #" invoice-number " on " date " for " total )))))
(println tempfile)
#_(io/copy tempfile (io/file "resources" "public" filename))
(for [{:keys [total date invoice-number customer-identifier]} (parse/parse-file (.getPath tempfile))]
{"customer-identifier" customer-identifier
"invoice-number" invoice-number
"date" date
"total" total})))
(route/resources "/")
(route/not-found "Not Found"))

View File

@@ -0,0 +1,9 @@
(ns auto-ap.server
(:require [auto-ap.handler :refer [app]]
[config.core :refer [env]]
[ring.adapter.jetty :refer [run-jetty]])
(:gen-class))
(defn -main [& args]
(let [port (Integer/parseInt (or (env :port) "3000"))]
(run-jetty app {:port port :join? false})))

View File

@@ -0,0 +1,4 @@
(ns auto-ap.config)
(def debug?
^boolean goog.DEBUG)

View File

@@ -0,0 +1,23 @@
(ns auto-ap.core
(:require [reagent.core :as reagent]
[re-frame.core :as re-frame]
[auto-ap.events :as events]
[auto-ap.views :as views]
[auto-ap.config :as config]))
(defn dev-setup []
(when config/debug?
(enable-console-print!)
(println "dev mode")))
(defn mount-root []
(re-frame/clear-subscription-cache!)
(reagent/render [views/main-panel]
(.getElementById js/document "app")))
(defn ^:export init []
(re-frame/dispatch-sync [::events/initialize-db])
(dev-setup)
(mount-root))

5
src/cljs/auto_ap/db.cljs Normal file
View File

@@ -0,0 +1,5 @@
(ns auto-ap.db)
(def default-db
{:company {:name "Campbell brewery"}
:invoices #{}})

View File

@@ -0,0 +1,13 @@
(ns auto-ap.events
(:require [re-frame.core :as re-frame]
[auto-ap.db :as db]))
(re-frame/reg-event-db
::initialize-db
(fn [_ _]
db/default-db))
(re-frame/reg-event-db
::imported-invoices
(fn [db [_ new-invoices]]
(update-in db [:invoices] into new-invoices)))

View File

@@ -0,0 +1,13 @@
(ns auto-ap.subs
(:require [re-frame.core :as re-frame]))
(re-frame/reg-sub
::name
(fn [db]
(:name (:company db))))
(re-frame/reg-sub
::invoices
(fn [db]
(:invoices db)))

149
src/cljs/auto_ap/views.cljs Normal file
View File

@@ -0,0 +1,149 @@
(ns auto-ap.views
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[auto-ap.subs :as subs]
[auto-ap.events :as events]))
(def dropzone
(with-meta
(fn []
[:form {:action "/pdf-upload" :class ".dropzone"}
[:div {:class "card"}
[:div {:class "card-header"}
[:span {:class "card-header-title"} "Upload Invoices"]]
[:div {:class "card-content"}
[:span {:class "icon"}
[:i {:class "fa fa-cloud-download"}]]
"Drop invoice pdfs here"
[:input {:type "file", :name "file", :style {:display "none"}}]]]])
{:component-did-mount (fn [this]
(-> (js/$ (reagent/dom-node this))
(.dropzone (clj->js {:init (fn []
(this-as t
(.on t "success" (fn [_ files]
(re-frame/dispatch [::events/imported-invoices (js->clj (.parse js/JSON files))])
))))
:url "/pdf-upload"}))))})
)
(defn main-panel []
(let [name (re-frame/subscribe [::subs/name])
invoices (re-frame/subscribe [::subs/invoices])]
(println name)
[:div
[:nav {:class "navbar has-shadow"}
[:div {:class "container"}
[:div {:class "navbar-brand"}
[:a {:class "navbar-item", :href "../"}
[:h1 (str "Auto-ap - " @name)]]
[:div {:class "navbar-burger burger", :data-target "navMenu"}
[:span]
[:span]
[:span]]]
[:div {:id "navMenu", :class "navbar-menu"}
[:div {:class "navbar-end"}
[:div {:class "navbar-item has-dropdown is-active"}
[:a {:class "navbar-link login"} ]
[:div {:class "navbar-dropdown", :style {:display "none"}}
[:a {:class "navbar-item"} ]
[:a {:class "navbar-item"} ]
[:a {:class "navbar-item"} ]
[:hr {:class "navbar-divider"}]
[:div {:class "navbar-item"} ]]]]]]]
[:div {:class "columns", :id "mail-app"}
[:aside {:class "column is-narrow aside hero is-fullheight"}
[:div.left-nav
[:div {:class "compose has-text-centered"}
[:a {:class "button is-danger is-block is-bold"}
[:span {:class "compose"} "New Invoice"]]]
[:div {:class "main"}
[:a {:href "#", :class "item active"}
[:span {:class "icon"}
[:i {:class "fa fa-inbox"}]]
[:span {:class "name"} "Upload\n Invoices"]]
[:a {:href "#", :class "item"}
[:span {:class "icon"}
[:i {:class "fa fa-star"}]]
[:span {:class "name"} "Unpaid Invoices"]]
[:a {:href "#", :class "item"}
[:span {:class "icon"}
[:i {:class "fa fa-envelope-o"}]]
[:span {:class "name"} "Paid Invoices"]]]]]
[:div {:class "column messages hero is-fullheight", :id "message-feed"}
[:div {:class "inbox-messages"}
[dropzone]
[:div {:class "section"}]
[:div {:class "card found-invoices", :style {:display (if (seq @invoices) "block" "none")}}
[:div {:class "card-header"}
[:span {:class "card-header-title"} "Found Invoices"]]
[:div {:class "card-content"}
[:table {:class "table", :style {:width "100%"}}
[:thead
[:tr
[:th "Customer"]
[:th "Invoice #"]
[:th "Date"]
[:th "Amount"]]]
[:tbody (for [{:strs [customer-identifier invoice-number date total]} @invoices]
^{:key (str customer-identifier "-" invoice-number)}
[:tr
[:td customer-identifier]
[:td invoice-number]
[:td date]
[:td total]])]]]]]]]
[:footer {:class "footer"}
[:div {:class "container"}
[:div {:class "content has-text-centered"}
[:p
[:strong "Auto-AP"]"by "
[:a {:href "https://github.com/"} "Integreat"]"."]
[:p
[:a {:class "icon", :href "https://github.com/dansup/bulma-templates"}
[:i {:class "fa fa-github"}]]]]]]]))
;;
;; <nav class="navbar has-shadow">
;; <div class="container">
;; <div class="navbar-brand">
;; <a class="navbar-item" href="../">
;; <h1>Auto-ap</h1>
;; </a>
;;
;; <div class="navbar-burger burger" data-target="navMenu">
;; <span></span>
;; <span></span>
;; <span></span>
;; </div>
;; </div>
;;
;; <div id="navMenu" class="navbar-menu">
;; <div class="navbar-end">
;; <div class="navbar-item has-dropdown is-active">
;; <a class="navbar-link login">
;; Login
;; </a>
;;
;; <div class="navbar-dropdown" style="display:none">
;; <a class="navbar-item">
;; Dashboard
;; </a>
;; <a class="navbar-item">
;; Profile
;; </a>
;; <a class="navbar-item">
;; Settings
;; </a>
;; <hr class="navbar-divider">
;; <div class="navbar-item">
;; Logout
;; </div>
;; </div>
;; </div>
;; </div>
;; </div>
;; </div>
;; </nav>