This commit is contained in:
Daniel O'Connell 2021-03-03 00:10:15 +01:00
parent 599472af37
commit 5d4159b3d7
8 changed files with 123 additions and 68 deletions

View File

@ -0,0 +1,49 @@
(ns chicken-master.api
(:require [chicken-master.orders :as orders]
[chicken-master.customers :as customers]
[chicken-master.products :as products]
[clojure.edn :as edn]
[compojure.core :refer [GET POST PUT DELETE defroutes]]))
(defn as-edn [resp]
{:headers {"Content-Type" "application/edn"}
:body resp})
(defn get-customers [user-id] (as-edn (customers/get-all user-id)))
(defn add-customer [{:keys [body basic-authentication]}]
(as-edn (some->> body :name (customers/create! basic-authentication))))
(defn delete-customer [user-id id] (->> id edn/read-string (customers/delete! user-id) as-edn))
(defn get-products [user-id] (as-edn (products/get-all user-id)))
(defn save-products [{:keys [body basic-authentication]}]
(some->> body (products/update! basic-authentication) (assoc {} :products) as-edn))
(defn get-orders [user-id] (as-edn (orders/get-all user-id)))
(defn update-order [request]
(let [user-id (:basic-authentication request)
id (some-> request :route-params :id (Integer/parseInt))
order (-> request :body (update :id #(or % id)))]
(as-edn (orders/replace! user-id order))))
(defn delete-order [user-id id] (->> id edn/read-string (orders/delete! user-id) as-edn))
(defn set-order-state [user-id id status] (as-edn (orders/change-state! user-id (edn/read-string id) status)))
(defn get-stock [user-id]
(as-edn
{:customers (:body (get-customers user-id))
:products (:body (get-products user-id))}))
(defroutes all-routes
(GET "/stock" [:as {user-id :basic-authentication}] (get-stock user-id))
(GET "/customers" [:as {user-id :basic-authentication}] (get-customers user-id))
(POST "/customers" request (add-customer request))
(DELETE "/customers/:id" [id :as {user-id :basic-authentication}] (delete-customer user-id id))
(GET "/products" request (get-products request))
(POST "/products" request (save-products request))
(GET "/orders" [:as {user-id :basic-authentication}] (get-orders user-id))
(POST "/orders" request (update-order request))
(PUT "/orders/:id" request (update-order request))
(DELETE "/orders/:id" [id :as {user-id :basic-authentication}] (delete-order user-id id))
(POST "/orders/:id/:status" [id status :as {user-id :basic-authentication}] (set-order-state user-id id status)))

View File

@ -1,64 +1,15 @@
(ns chicken-master.handler
(:require [chicken-master.db :as db]
[chicken-master.orders :as orders]
[chicken-master.customers :as customers]
[chicken-master.products :as products]
[chicken-master.api :as endpoints]
[clojure.edn :as edn]
[config.core :refer [env]]
[compojure.core :refer [GET POST PUT DELETE defroutes]]
[compojure.core :refer [GET defroutes routes]]
[compojure.route :refer [resources not-found]]
[compojure.handler :refer [api]]
[ring.util.response :refer [resource-response]]
[ring.middleware.basic-authentication :refer [wrap-basic-authentication]]
[ring.middleware.cors :refer [wrap-cors]]))
(defn as-edn [resp]
{:headers {"Content-Type" "application/edn"}
:body resp})
(defn get-customers [user-id] (as-edn (customers/get-all user-id)))
(defn add-customer [{:keys [body basic-authentication]}]
(as-edn (some->> body :name (customers/create! basic-authentication))))
(defn delete-customer [user-id id] (->> id edn/read-string (customers/delete! user-id) as-edn))
(defn get-products [user-id] (as-edn (products/get-all user-id)))
(defn save-products [{:keys [body basic-authentication]}]
(some->> body (products/update! basic-authentication) (assoc {} :products) as-edn))
(defn get-orders [user-id] (as-edn (orders/get-all user-id)))
(defn update-order [request]
(let [user-id (:basic-authentication request)
id (some-> request :route-params :id (Integer/parseInt))
order (-> request :body (update :id #(or % id)))]
(as-edn (orders/replace! user-id order))))
(defn delete-order [user-id id] (->> id edn/read-string (orders/delete! user-id) as-edn))
(defn set-order-state [user-id id status] (as-edn (orders/change-state! user-id (edn/read-string id) status)))
(defn get-stock [user-id]
(as-edn
{:customers (:body (get-customers user-id))
:products (:body (get-products user-id))}))
(defroutes routes
(GET "/stock" [:as {user-id :basic-authentication}] (get-stock user-id))
(GET "/customers" [:as {user-id :basic-authentication}] (get-customers user-id))
(POST "/customers" request (add-customer request))
(DELETE "/customers/:id" [id :as {user-id :basic-authentication}] (delete-customer user-id id))
(GET "/products" request (get-products request))
(POST "/products" request (save-products request))
(GET "/orders" [:as {user-id :basic-authentication}] (get-orders user-id))
(POST "/orders" request (update-order request))
(PUT "/orders/:id" request (update-order request))
(DELETE "/orders/:id" [id :as {user-id :basic-authentication}] (delete-order user-id id))
(POST "/orders/:id/:status" [id status :as {user-id :basic-authentication}] (set-order-state user-id id status))
(GET "/" [] (resource-response "index.html" {:root "public"}))
(resources "/")
(not-found "not found"))
(defn- handle-edn [response]
(if (= (get-in response [:headers "Content-Type"]) "application/edn")
(update response :body pr-str)
@ -82,10 +33,17 @@
(defn authenticated? [name pass]
(db/valid-user? name pass))
(def handler (-> routes
(defroutes base-routes
(GET "/" [] (resource-response "index.html" {:root "public"}))
(resources "/")
(not-found "not found"))
(def handler (routes
(-> endpoints/all-routes
(wrap-basic-authentication authenticated?)
(wrap-cors :access-control-allow-origin (map re-pattern (env :allow-origin))
:access-control-allow-methods [:get :put :post :delete :options])
api
wrap-edn-request
wrap-edn-response))
wrap-edn-response)
base-routes))

View File

@ -65,6 +65,8 @@
(defn settings-options []
[:div
[:h3 "Ustawienia wyglądu kalendarza"]
[:button {:type :button :on-click #(set-item! :bearer-token nil)} "wyloguj"]
(input :first-day-offset "o ile dni przesunąć niedziele w lewo"
{:type :number :max 7 :min 0 :parser #(js/parseInt %)})
(input :day-names "skróty nazw dni tygodnia"

View File

@ -25,6 +25,7 @@
;; :current-days [{:day (google.date "2020-01-01") :orders []}]
;; :customers []
;; :bearer-token "user-token"
::clients {:show nil} ; customers edit modal
:stock {:show nil}
:products {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21}

View File

@ -3,9 +3,10 @@
[re-frame.core :as re-frame]
[chicken-master.db :as db]
[chicken-master.time :as time]
[chicken-master.config :refer [settings default-settings]]
[chicken-master.config :refer [settings default-settings set-item!]]
[day8.re-frame.http-fx]
[ajax.edn :as edn]))
[ajax.edn :as edn]
[goog.crypt.base64 :as b64]))
(defn http-request [method endpoint & {:keys [params body on-success on-failure]
:or {on-success ::process-fetched-days
@ -13,7 +14,7 @@
{:method method
:uri (str (settings :backend-url) endpoint)
:headers {"Content-Type" "application/edn"
"authorization" "Basic c2lsb2E6a3JhY2g="}
"authorization" (str "Basic " (some-> js/window (.-localStorage) (.getItem :bearer-token)))}
:format (edn/edn-request-format)
:body (some-> body pr-str)
:params params
@ -21,6 +22,7 @@
:on-success [on-success]
:on-failure [on-failure]})
(defn http-get [endpoint params on-success]
(http-request :get endpoint :params params :on-success on-success))
@ -31,8 +33,17 @@
::initialize-db
(fn [_ _]
(time/update-settings default-settings)
{:db (assoc db/default-db :settings default-settings)
:fx [[:dispatch [::show-from-date (time/iso-date (time/today))]]
(let [user (some-> js/window (.-localStorage) (.getItem :bearer-token))]
{:db (assoc db/default-db
:settings default-settings
:current-user user)
:dispatch [(when user ::load-db)]})))
(re-frame/reg-event-fx
::load-db
(fn [_ _]
(time/update-settings default-settings)
{:fx [[:dispatch [::show-from-date (time/iso-date (time/today))]]
[:dispatch [::start-loading]]
[:dispatch [::fetch-stock]]
[:dispatch [::fetch-orders]]]}))
@ -52,7 +63,9 @@
(fn [db [_ response]]
(.error js/console (str response))
(js/alert "Wystąpił błąd")
(assoc db :loading? false)))
(-> db
(assoc :loading? false)
(update :current-user #(when-not (= (:status response) 401) %)))))
(re-frame/reg-event-fx
::remove-order
@ -191,6 +204,14 @@
(assoc-in db [:settings :show] true)))
(re-frame/reg-event-fx
::set-user
(fn [{db :db} [_ user]]
(set-item! :bearer-token (b64/encodeString (str (user "name") ":" (user "password"))))
{:db (assoc db :current-user (b64/encodeString (str (user "name") ":" (user "password"))))
:dispatch [::load-db]}))
(comment
(re-frame/dispatch-sync [::show-stock])
(re-frame/dispatch-sync [::update-product-stock :eggs 2])

View File

@ -39,8 +39,9 @@
content
[:div {:class :form-buttons}
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "ok"]]]])
([modal-id content & {:keys [on-submit submit-text]
:or {submit-text "ok"}}]
([modal-id content & {:keys [on-submit submit-text show-cancel]
:or {submit-text "ok"
show-cancel true}}]
[:div {:class :popup :on-click #(re-frame/dispatch [::event/hide-modal modal-id])}
[:form {:action "#"
:class :popup-content
@ -52,7 +53,8 @@
content
[:div {:class :form-buttons}
[:button submit-text]
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "anuluj"]]]]))
(when show-cancel
[:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "anuluj"])]]]))
(comment

View File

@ -2,6 +2,7 @@
(:require [re-frame.core :as re-frame]))
(re-frame/reg-sub ::name (fn [db] (:name db)))
(re-frame/reg-sub ::current-user (fn [db] (:current-user db)))
(re-frame/reg-sub ::settings (fn [db] (:settings db)))
(re-frame/reg-sub ::loading? (fn [db] (:loading? db)))

View File

@ -12,7 +12,23 @@
(defn show-settings []
(html/modal :settings (settings-options)))
(defn main-panel []
(defn login-screen []
[:div
(html/modal
:login
[:div
[:div
[:label {:for :name} "nazwa użytkownika"]
[:br]
[:input {:id :name :name :name}]]
[:div
[:label {:for :name} "hasło"]
[:br]
[:input {:id :password :name :password :type :password}]]]
:on-submit #(re-frame/dispatch [::event/set-user %])
:show-cancel nil)])
(defn app []
[:div {:class :full-height}
[:div {:class [:loader-container (if-not @(re-frame/subscribe [::subs/loading?]) :hidden)]}
[:div {:class :loader}]]
@ -36,3 +52,8 @@
(cal/calendar @(re-frame/subscribe [::subs/current-days]) @(re-frame/subscribe [::subs/settings]))
[:button {:id :scroll-down-button :class [:menu-button :scroll-button] :on-click #(re-frame/dispatch [::event/scroll-weeks 2])} "v"]
])
(defn main-panel []
(if @(re-frame/subscribe [::subs/current-user])
(app)
(login-screen)))