It looks okay now.
This commit is contained in:
@@ -2,5 +2,5 @@ FROM openjdk:8-jre-alpine
|
|||||||
RUN apk update
|
RUN apk update
|
||||||
RUN apk add poppler
|
RUN apk add poppler
|
||||||
RUN apk add poppler-utils
|
RUN apk add poppler-utils
|
||||||
COPY target/auto-ap-0.1.0-SNAPSHOT-standalone.jar /usr/local/
|
COPY target/auto-ap.jar /usr/local/
|
||||||
CMD java -jar /usr/local/auto-ap-0.1.0-SNAPSHOT-standalone.jar
|
CMD java -jar /usr/local/auto-ap.jar
|
||||||
|
|||||||
13
project.clj
13
project.clj
@@ -7,7 +7,8 @@
|
|||||||
[reagent "0.7.0"]
|
[reagent "0.7.0"]
|
||||||
[re-frame "0.10.2"]
|
[re-frame "0.10.2"]
|
||||||
[compojure "1.6.0"]
|
[compojure "1.6.0"]
|
||||||
[secretary "1.2.3"]
|
[kibu/pushy "0.3.8"]
|
||||||
|
[bidi "2.1.2"]
|
||||||
[ring/ring-defaults "0.2.1"]
|
[ring/ring-defaults "0.2.1"]
|
||||||
[ring/ring-json "0.4.0"]
|
[ring/ring-json "0.4.0"]
|
||||||
[ring "1.4.0"]
|
[ring "1.4.0"]
|
||||||
@@ -24,7 +25,8 @@
|
|||||||
:aliases {"dev" ["do" "clean"
|
:aliases {"dev" ["do" "clean"
|
||||||
["pdo" ["figwheel" "dev"]]]
|
["pdo" ["figwheel" "dev"]]]
|
||||||
"build" ["do" "clean"
|
"build" ["do" "clean"
|
||||||
["cljsbuild" "once" "min"]]}
|
["cljsbuild" "once" "min"]
|
||||||
|
["uberjar"]]}
|
||||||
|
|
||||||
:profiles
|
:profiles
|
||||||
{:dev
|
{:dev
|
||||||
@@ -44,7 +46,7 @@
|
|||||||
:compiler {:main auto-ap.core
|
:compiler {:main auto-ap.core
|
||||||
:output-to "resources/public/js/compiled/app.js"
|
:output-to "resources/public/js/compiled/app.js"
|
||||||
:output-dir "resources/public/js/compiled/out"
|
:output-dir "resources/public/js/compiled/out"
|
||||||
:asset-path "js/compiled/out"
|
:asset-path "/js/compiled/out"
|
||||||
:source-map-timestamp true
|
:source-map-timestamp true
|
||||||
:preloads [devtools.preload]
|
:preloads [devtools.preload]
|
||||||
:external-config {:devtools/config {:features-to-install :all}}
|
:external-config {:devtools/config {:features-to-install :all}}
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
:jar true
|
:jar true
|
||||||
:compiler {:main auto-ap.core
|
:compiler {:main auto-ap.core
|
||||||
:output-to "resources/public/js/compiled/app.js"
|
:output-to "resources/public/js/compiled/app.js"
|
||||||
:optimizations :advanced
|
:optimizations :whitespace
|
||||||
:closure-defines {goog.DEBUG false}
|
:closure-defines {goog.DEBUG false}
|
||||||
:pretty-print false}}
|
:pretty-print false}}
|
||||||
|
|
||||||
@@ -68,6 +70,5 @@
|
|||||||
|
|
||||||
:uberjar-name "auto-ap.jar"
|
:uberjar-name "auto-ap.jar"
|
||||||
|
|
||||||
#_#_:prep-tasks [["cljsbuild" "once" "min"]"compile"])
|
:prep-tasks [["cljsbuild" "once" "min"] "compile"])
|
||||||
|
|
||||||
;;
|
|
||||||
|
|||||||
@@ -325,7 +325,7 @@
|
|||||||
*/
|
*/
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
<script src="js/compiled/app.js"></script>
|
<script src="/js/compiled/app.js"></script>
|
||||||
<script>auto_ap.core.init();</script>
|
<script>auto_ap.core.init();</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
[ring.middleware.json :refer [wrap-json-response]]))
|
[ring.middleware.json :refer [wrap-json-response]]))
|
||||||
|
|
||||||
(defroutes app-routes
|
(defroutes app-routes
|
||||||
(GET "/hi" [] "hello")
|
|
||||||
(GET "/" [] (response/resource-response "index.html" {:root "public"}))
|
(GET "/" [] (response/resource-response "index.html" {:root "public"}))
|
||||||
(POST "/pdf-upload"
|
(POST "/pdf-upload"
|
||||||
{{ files "file"} :params :as params}
|
{{ files "file"} :params :as params}
|
||||||
@@ -22,6 +21,9 @@
|
|||||||
"date" date
|
"date" date
|
||||||
"total" total})))
|
"total" total})))
|
||||||
(route/resources "/")
|
(route/resources "/")
|
||||||
|
(routes (ANY "*" [] (response/resource-response "index.html" {:root "public"})))
|
||||||
|
|
||||||
|
|
||||||
(route/not-found "Not Found"))
|
(route/not-found "Not Found"))
|
||||||
|
|
||||||
#_(defroutes routes
|
#_(defroutes routes
|
||||||
|
|||||||
@@ -3,11 +3,20 @@
|
|||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[auto-ap.events :as events]
|
[auto-ap.events :as events]
|
||||||
[auto-ap.views :as views]
|
[auto-ap.views :as views]
|
||||||
[auto-ap.config :as config]))
|
[auto-ap.config :as config]
|
||||||
|
[auto-ap.routes :as routes]
|
||||||
|
[pushy.core :as pushy]
|
||||||
|
[bidi.bidi :as bidi]))
|
||||||
|
|
||||||
|
(defn- parse-url [url]
|
||||||
|
(.log js/console "test" (bidi/match-route routes/routes url))
|
||||||
|
(bidi/match-route routes/routes url))
|
||||||
|
|
||||||
|
(defn- dispatch-route [matched-route]
|
||||||
|
(re-frame/dispatch [::events/set-active-page (:handler matched-route)]))
|
||||||
|
|
||||||
(defn dev-setup []
|
(defn dev-setup []
|
||||||
(when config/debug?
|
(when true
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
(println "dev mode")))
|
(println "dev mode")))
|
||||||
|
|
||||||
@@ -17,7 +26,9 @@
|
|||||||
(.getElementById js/document "app")))
|
(.getElementById js/document "app")))
|
||||||
|
|
||||||
(defn ^:export init []
|
(defn ^:export init []
|
||||||
(re-frame/dispatch-sync [::events/initialize-db])
|
|
||||||
(dev-setup)
|
(dev-setup)
|
||||||
|
(pushy/start! (pushy/pushy dispatch-route parse-url))
|
||||||
|
(re-frame/dispatch-sync [::events/initialize-db])
|
||||||
(mount-root))
|
(mount-root))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
(def default-db
|
(def default-db
|
||||||
{:company {:name "Campbell brewery"}
|
{:company {:name "Campbell brewery"}
|
||||||
:invoices #{}})
|
:invoices #{}
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
(ns auto-ap.events
|
(ns auto-ap.events
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[auto-ap.db :as db]))
|
[auto-ap.db :as db]
|
||||||
|
[auto-ap.routes :as routes]
|
||||||
|
[bidi.bidi :as bidi]))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::initialize-db
|
::initialize-db
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
db/default-db))
|
(assoc db/default-db
|
||||||
|
:active-page (:handler (bidi/match-route routes/routes (.. js/window -location -pathname))))))
|
||||||
|
|
||||||
|
(re-frame/reg-event-db
|
||||||
|
::set-active-page
|
||||||
|
(fn [db [_ active-page]]
|
||||||
|
(assoc db :active-page active-page)))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::imported-invoices
|
::imported-invoices
|
||||||
|
|||||||
8
src/cljs/auto_ap/routes.cljs
Normal file
8
src/cljs/auto_ap/routes.cljs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
(ns auto-ap.routes
|
||||||
|
(:require [bidi.bidi :as bidi]))
|
||||||
|
|
||||||
|
(def routes ["/" {"" :index
|
||||||
|
"invoices/" {"" :invoices
|
||||||
|
"import" :import-invoices
|
||||||
|
"unpaid" :unpaid-invoices
|
||||||
|
"paid" :paid-invoices}}])
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
(fn [db]
|
(fn [db]
|
||||||
(:name (:company db))))
|
(:name (:company db))))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
::active-page
|
||||||
|
(fn [db]
|
||||||
|
(:active-page db)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
::invoices
|
::invoices
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[auto-ap.subs :as subs]
|
[auto-ap.subs :as subs]
|
||||||
[auto-ap.events :as events]))
|
[auto-ap.events :as events]
|
||||||
|
[auto-ap.routes :as routes]
|
||||||
|
[bidi.bidi :as bidi]))
|
||||||
|
|
||||||
|
(defn active-when= [active-page candidate]
|
||||||
|
(when (= active-page candidate) " active"))
|
||||||
|
|
||||||
(def dropzone
|
(def dropzone
|
||||||
(with-meta
|
(with-meta
|
||||||
@@ -17,90 +22,132 @@
|
|||||||
"Drop invoice pdfs here"
|
"Drop invoice pdfs here"
|
||||||
[:input {:type "file", :name "file", :style {:display "none"}}]]]])
|
[:input {:type "file", :name "file", :style {:display "none"}}]]]])
|
||||||
{:component-did-mount (fn [this]
|
{:component-did-mount (fn [this]
|
||||||
(-> (js/$ (reagent/dom-node this))
|
(js/Dropzone. (reagent/dom-node this)
|
||||||
(.dropzone (clj->js {:init (fn []
|
(clj->js {:init (fn []
|
||||||
(this-as t
|
(.on (js-this) "success" (fn [_ files]
|
||||||
(.on t "success" (fn [_ files]
|
(re-frame/dispatch [::events/imported-invoices (js->clj (.parse js/JSON files))])
|
||||||
(re-frame/dispatch [::events/imported-invoices (js->clj (.parse js/JSON files))])
|
)))
|
||||||
))))
|
:url "/pdf-upload"})))}))
|
||||||
:url "/pdf-upload"}))))})
|
|
||||||
)
|
(defmulti active-page identity)
|
||||||
|
|
||||||
|
(defmethod active-page :index []
|
||||||
|
[:div {:class "inbox-messages"}
|
||||||
|
[:div.hero
|
||||||
|
[:div.hero-body
|
||||||
|
[:div.container
|
||||||
|
[:h1.title "Dashboard"]
|
||||||
|
[:h2.subtitle "To get started, "
|
||||||
|
[:a {:href (bidi/path-for routes/routes :import-invoices)} "Import some invoices"]]]]]])
|
||||||
|
|
||||||
|
(defmethod active-page :unpaid-invoices []
|
||||||
|
[:div {:class "inbox-messages"}
|
||||||
|
[:h1.title "Unpaid invoices"]])
|
||||||
|
|
||||||
|
(defmethod active-page :paid-invoices []
|
||||||
|
[:div {:class "inbox-messages"}
|
||||||
|
[:h1.title "Paid invoices"]])
|
||||||
|
|
||||||
|
(defmethod active-page :invoices []
|
||||||
|
[:div {:class "inbox-messages"}
|
||||||
|
[:h1.title "All invoices"]])
|
||||||
|
|
||||||
|
(defmethod active-page :import-invoices []
|
||||||
|
(let [invoices (re-frame/subscribe [::subs/invoices])]
|
||||||
|
[:div {:class "inbox-messages"}
|
||||||
|
[:h1.title "Upload invoices"]
|
||||||
|
[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]])]]]]]))
|
||||||
|
|
||||||
(defn main-panel []
|
(defn main-panel []
|
||||||
(let [name (re-frame/subscribe [::subs/name])
|
(let [name (re-frame/subscribe [::subs/name])
|
||||||
invoices (re-frame/subscribe [::subs/invoices])]
|
ap (re-frame/subscribe [::subs/active-page])]
|
||||||
(println name)
|
|
||||||
[:div
|
[:div
|
||||||
[:nav {:class "navbar has-shadow"}
|
[:nav {:class "navbar has-shadow"}
|
||||||
[:div {:class "container"}
|
[:div {:class "container"}
|
||||||
[:div {:class "navbar-brand"}
|
[:div {:class "navbar-brand"}
|
||||||
[:a {:class "navbar-item", :href "../"}
|
[:a {:class "navbar-item", :href "../"}
|
||||||
[:h1 (str "Auto-ap - " @name)]]
|
[:h1 (str "Auto-ap - " @name)]]
|
||||||
[:div {:class "navbar-burger burger", :data-target "navMenu"}
|
[:div {:class "navbar-burger burger", :data-target "navMenu"}
|
||||||
[:span]
|
[:span]
|
||||||
[:span]
|
[:span]
|
||||||
[:span]]]
|
[:span]]]
|
||||||
[:div {:id "navMenu", :class "navbar-menu"}
|
[:div {:id "navMenu", :class "navbar-menu"}
|
||||||
[:div {:class "navbar-end"}
|
[:div {:class "navbar-end"}
|
||||||
[:div {:class "navbar-item has-dropdown is-active"}
|
[:div {:class "navbar-item has-dropdown is-active"}
|
||||||
[:a {:class "navbar-link login"} ]
|
[:a {:class "navbar-link login"} ]
|
||||||
[:div {:class "navbar-dropdown", :style {:display "none"}}
|
[:div {:class "navbar-dropdown", :style {:display "none"}}
|
||||||
[:a {:class "navbar-item"} ]
|
[:a {:class "navbar-item"} ]
|
||||||
[:a {:class "navbar-item"} ]
|
[:a {:class "navbar-item"} ]
|
||||||
[:a {:class "navbar-item"} ]
|
[:a {:class "navbar-item"} ]
|
||||||
[:hr {:class "navbar-divider"}]
|
[:hr {:class "navbar-divider"}]
|
||||||
[:div {:class "navbar-item"} ]]]]]]]
|
[:div {:class "navbar-item"} ]]]]]]]
|
||||||
[:div {:class "columns", :id "mail-app"}
|
[:div {:class "columns", :id "mail-app"}
|
||||||
[:aside {:class "column is-narrow aside hero is-fullheight"}
|
[:aside {:class "column is-narrow aside menu hero is-fullheight"}
|
||||||
[:div.left-nav
|
[:div.main
|
||||||
[:div {:class "compose has-text-centered"}
|
[:p.menu-label "General"]
|
||||||
[:a {:class "button is-danger is-block is-bold"}
|
[:p.menu-item
|
||||||
[:span {:class "compose"} "New Invoice"]]]
|
[:a {:href (bidi/path-for routes/routes :index) , :class (str "item" (active-when= @ap :index))}
|
||||||
[:div {:class "main"}
|
[:span {:class "icon"}
|
||||||
[:a {:href "#", :class "item active"}
|
[:i {:class "fa fa-tachometer"}]]
|
||||||
[:span {:class "icon"}
|
[:span {:class "name"} "Dashboard"]]]
|
||||||
[:i {:class "fa fa-inbox"}]]
|
|
||||||
[:span {:class "name"} "Upload\n Invoices"]]
|
[:p.menu-label "Accounts Payable"]
|
||||||
[:a {:href "#", :class "item"}
|
[:ul.menu-list
|
||||||
[:span {:class "icon"}
|
[:li.menu-item
|
||||||
[:i {:class "fa fa-star"}]]
|
[:a {:href (bidi/path-for routes/routes :import-invoices) , :class (str "item" (active-when= @ap :import-invoices))}
|
||||||
[:span {:class "name"} "Unpaid Invoices"]]
|
[:span {:class "icon"}
|
||||||
[:a {:href "#", :class "item"}
|
[:i {:class "fa fa-star-o"}]]
|
||||||
[:span {:class "icon"}
|
|
||||||
[:i {:class "fa fa-envelope-o"}]]
|
[:span {:class "name"} "Upload Invoices"]]]
|
||||||
[:span {:class "name"} "Paid Invoices"]]]]]
|
[:li.menu-item
|
||||||
[:div {:class "column messages hero is-fullheight", :id "message-feed"}
|
[:a {:href (bidi/path-for routes/routes :unpaid-invoices), :class (str "item" (active-when= @ap :unpaid-invoices))}
|
||||||
[:div {:class "inbox-messages"}
|
[:span {:class "icon"}
|
||||||
[dropzone]
|
[:i {:class "fa fa-envelope-o"}]]
|
||||||
|
[:span {:class "name"} "Unpaid Invoices"]]
|
||||||
[:div {:class "section"}]
|
]
|
||||||
[:div {:class "card found-invoices", :style {:display (if (seq @invoices) "block" "none")}}
|
[:li.menu-item
|
||||||
[:div {:class "card-header"}
|
[:a {:href (bidi/path-for routes/routes :paid-invoices), :class (str "item" (active-when= @ap :paid-invoices))}
|
||||||
[:span {:class "card-header-title"} "Found Invoices"]]
|
[:span {:class "icon"}
|
||||||
[:div {:class "card-content"}
|
[:i {:class "fa fa-envelope-o"}]]
|
||||||
[:table {:class "table", :style {:width "100%"}}
|
[:span {:class "name"} "Paid Invoices"]]
|
||||||
[:thead
|
]
|
||||||
[:tr
|
[:ul ]]]
|
||||||
[:th "Customer"]
|
|
||||||
[:th "Invoice #"]
|
[:div.left-nav
|
||||||
[:th "Date"]
|
[:div {:class "compose has-text-centered"}
|
||||||
[:th "Amount"]]]
|
[:a {:class "button is-danger is-block is-bold"}
|
||||||
[:tbody (for [{:strs [customer-identifier invoice-number date total]} @invoices]
|
[:span {:class "compose"} "New Invoice"]]]]]
|
||||||
^{:key (str customer-identifier "-" invoice-number)}
|
[:div {:class "column messages hero is-fullheight", :id "message-feed"}
|
||||||
[:tr
|
[active-page @ap]]]
|
||||||
[:td customer-identifier]
|
[:footer {:class "footer"}
|
||||||
[:td invoice-number]
|
[:div {:class "container"}
|
||||||
[:td date]
|
[:div {:class "content has-text-centered"}
|
||||||
[:td total]])]]]]]]]
|
[:p
|
||||||
[:footer {:class "footer"}
|
[:strong "Auto-AP"]"by "
|
||||||
[:div {:class "container"}
|
[:a {:href "https://github.com/"} "Integreat"]"."]
|
||||||
[:div {:class "content has-text-centered"}
|
[:p
|
||||||
[:p
|
[:a {:class "icon", :href "https://github.com/dansup/bulma-templates"}
|
||||||
[:strong "Auto-AP"]"by "
|
[:i {:class "fa fa-github"}]]]]]]]))
|
||||||
[:a {:href "https://github.com/"} "Integreat"]"."]
|
|
||||||
[:p
|
|
||||||
[:a {:class "icon", :href "https://github.com/dansup/bulma-templates"}
|
|
||||||
[:i {:class "fa fa-github"}]]]]]]]))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user