Now a simple re-frame app
This commit is contained in:
@@ -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"))
|
||||
|
||||
9
src/clj/auto_ap/server.clj
Normal file
9
src/clj/auto_ap/server.clj
Normal 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})))
|
||||
4
src/cljs/auto_ap/config.cljs
Normal file
4
src/cljs/auto_ap/config.cljs
Normal file
@@ -0,0 +1,4 @@
|
||||
(ns auto-ap.config)
|
||||
|
||||
(def debug?
|
||||
^boolean goog.DEBUG)
|
||||
23
src/cljs/auto_ap/core.cljs
Normal file
23
src/cljs/auto_ap/core.cljs
Normal 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
5
src/cljs/auto_ap/db.cljs
Normal file
@@ -0,0 +1,5 @@
|
||||
(ns auto-ap.db)
|
||||
|
||||
(def default-db
|
||||
{:company {:name "Campbell brewery"}
|
||||
:invoices #{}})
|
||||
13
src/cljs/auto_ap/events.cljs
Normal file
13
src/cljs/auto_ap/events.cljs
Normal 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)))
|
||||
13
src/cljs/auto_ap/subs.cljs
Normal file
13
src/cljs/auto_ap/subs.cljs
Normal 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
149
src/cljs/auto_ap/views.cljs
Normal 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>
|
||||
|
||||
Reference in New Issue
Block a user