diff --git a/project.clj b/project.clj index ba2cc63..ee6134c 100644 --- a/project.clj +++ b/project.clj @@ -7,10 +7,13 @@ [thheller/shadow-cljs "2.11.0"] [reagent "0.10.0"] [re-frame "1.1.1"] + [day8.re-frame/http-fx "0.2.2"] [garden "1.3.10"] [ns-tracker "0.4.0"] [compojure "1.6.2"] [yogthos/config "1.1.7"] + [ring-basic-authentication "1.1.0"] + [ring-cors "0.1.13"] [ring "1.8.1"]] :plugins [[lein-shadow "0.2.2"] @@ -34,7 +37,7 @@ :pretty-print? true}}]} :shadow-cljs {:nrepl {:port 8777} - + :builds {:app {:target :browser :output-dir "resources/public/js/compiled" :asset-path "/js/compiled" @@ -45,14 +48,14 @@ :http-port 8280 :http-handler chicken-master.handler/dev-handler }}}} - + :shell {:commands {"karma" {:windows ["cmd" "/c" "karma"] :default-command "karma"} "open" {:windows ["cmd" "/c" "start"] :macosx "open" :linux "xdg-open"}}} - :aliases {"dev" ["do" + :aliases {"dev" ["do" ["shell" "echo" "\"DEPRECATED: Please use lein watch instead.\""] ["watch"]] "watch" ["with-profile" "dev" "do" @@ -82,7 +85,7 @@ :source-paths ["dev"]} :prod {} - + :uberjar {:source-paths ["env/prod/clj"] :omit-source true :main chicken-master.server diff --git a/src/clj/chicken_master/handler.clj b/src/clj/chicken_master/handler.clj index 151c28d..0f9062d 100644 --- a/src/clj/chicken_master/handler.clj +++ b/src/clj/chicken_master/handler.clj @@ -1,15 +1,81 @@ (ns chicken-master.handler - (:require - [compojure.core :refer [GET defroutes]] - [compojure.route :refer [resources]] - [ring.util.response :refer [resource-response]] - [ring.middleware.reload :refer [wrap-reload]] - [shadow.http.push-state :as push-state])) + (:require [chicken-master.mocks :as mocks] + [clojure.edn :as edn] + [compojure.core :refer [GET POST PUT DELETE defroutes]] + [compojure.route :refer [resources]] + [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 get-customers [] {:body (mocks/fetch-customers {})}) +(defn add-customer [request] {:body (some-> request :body :name mocks/add-customer)}) + +(defn get-products [_] (prn _){:body (mocks/get-all-products)}) +(defn save-products [request] {:body (some-> request :body mocks/save-stocks)}) + +(defn get-orders [params] {:body {:orders (mocks/get-orders params)}}) +(defn update-order [request] + (let [id (some-> request :route-params :id (Integer/parseInt)) + body (some->> request :body)] + {:body (mocks/replace-order id body)})) + +(defn delete-order [id] {:body (mocks/delete-order (edn/read-string id))}) +(defn set-order-state [id status] (prn "asd"){:body (mocks/order-state (edn/read-string id) status)}) + +(defn get-stock [params] + {:body + {:customers (:body (get-customers)) + :products (:body (get-products params))}}) (defroutes routes + (GET "/stock" {params :query-params} (get-stock params)) + (GET "/customers" [] (get-customers)) + (POST "/customers" request (add-customer request)) + + (GET "/products" request (get-products request)) + (POST "/products" request (save-products request)) + + (GET "/orders" {params :query-params} (get-orders params)) + (POST "/orders" request (update-order request)) + (PUT "/orders/:id" request (update-order request)) + (DELETE "/orders/:id" [id] (delete-order id)) + (POST "/orders/:id/:status" [id status] (set-order-state id status)) + (GET "/" [] (resource-response "index.html" {:root "public"})) (resources "/")) -(def dev-handler (-> #'routes wrap-reload push-state/handle)) -(def handler routes) +(defn- handle-edn [response] + (if (string? (:body response)) + response + (-> response + (assoc-in [:headers "Content-Type"] "application/edn") + (update :body pr-str)))) + +(defn wrap-edn-response [handler] + (fn + ([request] + (-> request handler handle-edn)) + ([request respond raise] + (-> request handler handle-edn respond)))) + +(defn wrap-edn-request [handler] + (fn + ([request] + (handler + (if (= (:content-type request) "application/edn") + (update request :body (comp edn/read-string slurp)) + request))))) + +(defn authenticated? [name pass] + (and (= name "siloa") + (= pass "krach"))) + +(def handler (-> routes + (wrap-basic-authentication authenticated?) + (wrap-cors :access-control-allow-origin [#"http://localhost:8280"] + :access-control-allow-methods [:get :put :post :delete :options]) + api + wrap-edn-request + wrap-edn-response)) diff --git a/src/clj/chicken_master/mocks.clj b/src/clj/chicken_master/mocks.clj new file mode 100644 index 0000000..7a53120 --- /dev/null +++ b/src/clj/chicken_master/mocks.clj @@ -0,0 +1,95 @@ +(ns chicken-master.mocks + (:import [java.time Instant] + [java.time.temporal ChronoUnit])) + + +(defn format-date [d] (-> d str (subs 0 10))) + +(defn days-range [days date ] + (map #(.plus date % ChronoUnit/DAYS) (range days))) + +;;;; Stock + +(def stock-products (atom {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21})) + +(defn get-all-products [] @stock-products) +(defn save-stocks [new-products] (reset! stock-products new-products)) + +;;; Orders + +(def id-counter (atom -1)) +(def notes ["bezglutenowy" + "tylko z robakami" + "przyjdzie wieczorem" + "wisi 2.50" + "chciała ukraść kozę"]) +(def products (atom [:eggs :milk :cabbage :carrots])) +(def customers (atom [{:id 1 :name "mr.blobby (649 234 234)"} + {:id 2 :name "da police (0118 999 881 999 119 725 123123 12 3123 123 )"} + {:id 3 :name "johnny"}])) +(def orders + (atom + (->> (-> (Instant/now) (.minus 50 ChronoUnit/DAYS)) + (days-range 90) + (map (fn [date] + [(format-date date) (repeatedly (rand-int 6) #(swap! id-counter inc))])) + (map (fn [[day ids]] + (map (fn [i] + {:id i :day day + :notes (when (> (rand) 0.7) (rand-nth notes)) + :state :waiting + :who (rand-nth @customers) + :products (->> @products + (random-sample 0.4) + (map #(vector % (rand-int 10))) + (into {})) + }) ids) + )) + flatten + (map #(vector (:id %) %)) + (into {})))) + + +(defn fetch-customers [_] + @customers) + +(defn fetch-stock [params] + {:customers (fetch-customers params) + :products (get-all-products)}) + +(defn add-customer [customer-name] + (swap! customers conj {:id (->> @customers (map :id) (apply max) inc) + :name customer-name}) + (fetch-stock {})) + +(defn day-customers [day] [day (->> @orders vals (filter (comp #{day} :day)))]) + +(defn get-orders [params] @orders) + +(defn replace-order [id order] + (println "replacing order" order) + (let [prev-day (:day (@orders (:id order))) + order (update order :id #(or % (swap! id-counter inc)))] + (prn "order 1" order) + (swap! orders assoc (:id order) order) + (prn "order 2" (@orders (:id order))) + (if (or (not prev-day) (= prev-day (:day order))) + {(:day order) (->> order :day day-customers second)} + {prev-day (->> prev-day day-customers second) + (:day order) (->> order :day day-customers second)}))) + +(defn delete-order [id] + (println "deleting order" id) + (let [day (-> (get @orders id) :day)] + (swap! orders #(dissoc % id)) + {day (->> day day-customers second)})) + +(defn order-state [id state] + (prn "fulfilling order" id state) + (condp = state + "fulfilled" (->> id (get @orders) :products (swap! stock-products #(merge-with - %1 %2))) + "waiting" (->> id (get @orders) :products (swap! stock-products #(merge-with + %1 %2)))) + (let [day (-> (get @orders id) :day)] + (swap! orders #(assoc-in % [id :state] (keyword state))) + (println id (get @orders id)) + {day (->> day day-customers second)})) diff --git a/src/clj/chicken_master/server.clj b/src/clj/chicken_master/server.clj index 30b7bfe..b44b0a0 100644 --- a/src/clj/chicken_master/server.clj +++ b/src/clj/chicken_master/server.clj @@ -7,3 +7,8 @@ (defn -main [& _args] (let [port (or (env :port) 3000)] (run-jetty handler {:port port :join? false}))) + +(def h + (let [port (or (env :port) 3000)] + (run-jetty handler {:port port :join? false}))) +(.stop h) diff --git a/src/cljs/chicken_master/backend_mocks.cljs b/src/cljs/chicken_master/backend_mocks.cljs index 66add50..dca9e33 100644 --- a/src/cljs/chicken_master/backend_mocks.cljs +++ b/src/cljs/chicken_master/backend_mocks.cljs @@ -6,17 +6,12 @@ (def stock-products (atom {:eggs 22 :milk 32 :cabbage 54 :carrots 11 :cows 32 :ants 21})) (defn get-all-products [] @stock-products) -(defn save-stocks [new-products] (reset! stock-products new-products)) +(defn save-stocks [new-products] + (reset! stock-products new-products)) ;;; Orders (def id-counter (atom -1)) -;; (def days (atom -;; (->> (time/date-offset (new js/Date) -50) -;; (time/days-range 90) -;; (map (fn [date] -;; [(time/iso-date date) (repeatedly (rand-int 6) #(swap! id-counter inc))])) -;; (into {})))) (def notes ["bezglutenowy" "tylko z robakami" "przyjdzie wieczorem" @@ -56,9 +51,11 @@ {:customers (fetch-customers params) :products (get-all-products)}) -(defn add-customer [{:keys [customer-name] :as params}] +(defn add-customer [{:keys [name] :as params}] + (prn name) (swap! customers conj {:id (->> @customers (map :id) (apply max) inc) - :name customer-name}) + :name name}) + (prn @customers) (fetch-stock params)) (defn- day-customers [day] [day (->> @orders vals (filter (comp #{day} :day)))]) @@ -67,31 +64,21 @@ (int (/ (- (time/parse-date to) (time/parse-date from)) (* 24 3600000))) (time/parse-date from))) -(defn fetch-days [{:keys [from to]}] - (->> (days-between from to) - (map time/iso-date) - (map day-customers) - (into {}))) +(defn fetch-orders [{:keys [from to]}] + {:orders @orders}) -(defn- replace-order [{start-from :start-from :as order}] +(defn- replace-order [id order] (println "replacing order" order) - (let [order (-> order - (dissoc :start-from) - (update :id #(or % (swap! id-counter inc))))] - (prn "order 1" order) + (let [prev-day (:day (get @orders id)) + order (update order :id #(or % (swap! id-counter inc)))] (swap! orders assoc (:id order) order) - (prn "order 2" (@orders (:id order))) - (if start-from - (->> start-from - time/start-of-week - (time/days-range 28) - (map time/iso-date) - (map day-customers) - (into {})) + (if prev-day + {prev-day (->> prev-day day-customers second) + (:day order) (->> order :day day-customers second)} {(:day order) (->> order :day day-customers second)}))) -(defn- delete-order [{id :id}] - (println "deleting order" id) +(defn- delete-order [id] + (println "deleting order" id (get @orders id)) (let [day (-> (get @orders id) :day)] (swap! orders #(dissoc % id)) {day (->> day day-customers second)})) diff --git a/src/cljs/chicken_master/calendar.cljs b/src/cljs/chicken_master/calendar.cljs index a45ea05..63365bf 100644 --- a/src/cljs/chicken_master/calendar.cljs +++ b/src/cljs/chicken_master/calendar.cljs @@ -51,13 +51,13 @@ (map prod/format-product) (into [:div {:class :products}]))]) -(defn day [{:keys [date orders]}] - [:div {:class [:day (when (time/today? date) :today)] +(defn day [[date orders]] + [:div {:class [:day (when (-> date time/parse-date time/today?) :today)] :on-drag-over #(.preventDefault %) :on-drop #(let [id (-> % .-dataTransfer (.getData "text") prod/num-or-nil)] (.preventDefault %) - (re-frame/dispatch [::event/move-order id (time/iso-date date)]))} - [:div {:class :day-header} (time/format-date date)] + (re-frame/dispatch [::event/move-order id date]))} + [:div {:class :day-header} (-> date time/parse-date time/format-date)] [:div [:div {:class :orders} (if (settings :hide-fulfilled-orders) @@ -65,7 +65,7 @@ (map format-order orders)) (when (settings :show-day-add-order) [:button {:type :button - :on-click #(re-frame/dispatch [::event/edit-order (time/iso-date date)])} "+"]) + :on-click #(re-frame/dispatch [::event/edit-order date])} "+"]) (when (seq (map :products orders)) [:div {:class :summary} [:hr {:class :day-seperator}] @@ -75,8 +75,7 @@ (apply merge-with +) (sort-by first) (map prod/format-product) - (into [:div {:class :products-sum}]))]) - ]]]) + (into [:div {:class :products-sum}]))])]]]) (defn calendar-header [] (->> (:day-names settings) diff --git a/src/cljs/chicken_master/config.cljs b/src/cljs/chicken_master/config.cljs index 72fbf8a..6a9f6f0 100644 --- a/src/cljs/chicken_master/config.cljs +++ b/src/cljs/chicken_master/config.cljs @@ -14,4 +14,7 @@ :show-order-notes true ; display notes :editable-number-inputs false ; only allow number modifications in the edit modal :hide-fulfilled-orders false + + :http-dispatch :http;-xhrio + :backend-url "http://localhost:3000/" }) diff --git a/src/cljs/chicken_master/customers.cljs b/src/cljs/chicken_master/customers.cljs index 83f74fe..33d4ef6 100644 --- a/src/cljs/chicken_master/customers.cljs +++ b/src/cljs/chicken_master/customers.cljs @@ -11,7 +11,7 @@ (defn order-adder [order] (let [state (reagent/atom order)] (fn [] - [:details {:class :customer-order :key (gensym) :open (:open @state)} + [:details {:class (or (:class order) :customer-order) :key (gensym) :open (:open @state)} [:summary {:on-click #(swap! state update :open not)} [prod/item-adder :type :date @@ -34,8 +34,8 @@ (for [{:keys [name id] :as who} @(re-frame/subscribe [::subs/available-customers])] [:details {:class "client" :key (gensym)} [:summary name] - (for [order (sort-by :day (client-orders id))] + [order-adder {:who who}] + (for [order (reverse (sort-by :day (client-orders id)))] [order-adder (assoc order :key (gensym))]) - [order-adder who :class :new-user] ]))] )) diff --git a/src/cljs/chicken_master/events.cljs b/src/cljs/chicken_master/events.cljs index 53d8c78..c0f4178 100644 --- a/src/cljs/chicken_master/events.cljs +++ b/src/cljs/chicken_master/events.cljs @@ -3,20 +3,40 @@ [re-frame.core :as re-frame] [chicken-master.db :as db] [chicken-master.time :as time] + [chicken-master.config :refer [settings]] + [day8.re-frame.http-fx] + [ajax.edn :as edn] ;; required for http mocks [chicken-master.backend-mocks :as mocks])) +(defn http-request [method endpoint & {:keys [params body on-success on-failure] + :or {on-success ::process-fetched-days + on-failure ::failed-blah}}] + {:method method + :uri (str (settings :backend-url) endpoint) + :headers {"Content-Type" "application/edn" + "authorization" "Basic c2lsb2E6a3JhY2g="} + :format (edn/edn-request-format) + :body (some-> body pr-str) + :params params + :response-format (edn/edn-response-format) + :on-success [on-success] + :on-fail [on-failure]}) + +(defn http-get [endpoint params on-success] + (http-request :get endpoint :params params :on-success on-success)) + +(defn http-post [endpoint body] + (http-request :post endpoint :body body)) + (re-frame/reg-event-fx ::initialize-db (fn [_ _] {:db db/default-db - :dispatch [::show-from-date (new js/Date)] - :http {:method :post - :url "get-stock" - :params {} - :on-success [::process-stock] - :on-fail [::failed-blah]}})) + :fx [[:dispatch [::show-from-date (time/iso-date (time/today))]] + [:dispatch [::fetch-stock]] + [:dispatch [::fetch-orders]]]})) (re-frame/reg-event-db ::hide-modal (fn [db [_ modal]] (assoc-in db [modal :show] nil))) @@ -29,20 +49,14 @@ (re-frame/reg-event-fx ::remove-order (fn [_ [_ id]] - {:http {:method :delete - :url "delete-order" - :params {:id id} - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + {(settings :http-dispatch) (http-request :delete (str "orders/" id))})) (re-frame/reg-event-fx ::move-order (fn [{{orders :orders start-date :start-date} :db} [_ id day]] - {:http {:method :post - :url "save-order" - :params (-> id orders (assoc :day day :start-from start-date)) - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + {(settings :http-dispatch) + (http-request :put (str "orders/" id) + :body (-> id orders (assoc :day day :start-from start-date)))})) (re-frame/reg-event-db ::edit-order @@ -56,107 +70,57 @@ ::fulfill-order (fn [{db :db} [_ id]] {:db (assoc-in db [:orders id :state] :pending) - :dispatch [::set-current-days] - :http {:method :post - :url "fulfill-order" - :params {:id id} - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + (settings :http-dispatch) (http-request :post (str "orders/" id "/fulfilled"))})) (re-frame/reg-event-fx ::reset-order (fn [{db :db} [_ id]] {:db (assoc-in db [:orders id :state] :waiting) - :fx [[:dispatch [::set-current-days]]] - :http {:method :post - :url "reset-order" - :params {:id id} - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + (settings :http-dispatch) (http-request :post (str "orders/" id "/waiting"))})) (re-frame/reg-event-fx ::save-order (fn [{{order :order-edit} :db} [_ form]] {:dispatch [::hide-modal :order-edit] - :http {:method :post - :url "save-order" - :params (merge - (select-keys order [:id :day :hour :state]) - (select-keys form [:id :day :hour :state :who :notes :products])) - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + (settings :http-dispatch) (http-post (str "orders") + (merge + (select-keys order [:id :day :hour :state]) + (select-keys form [:id :day :hour :state :who :notes :products])))})) (re-frame/reg-event-db - ::selected-product - (fn [db [_ product product-no]] - (let [db (assoc-in db [:order-edit :products product-no :prod] product)] - (if (-> db :order-edit :products last :prod) - (update-in db [:order-edit :products] conj {}) - db)))) -(re-frame/reg-event-db - ::changed-amount - (fn [db [_ amount product-no]] - (assoc-in db [:order-edit :products product-no :amount] amount))) - - -(defn get-day [{:keys [days orders]} date] - {:date date - :orders (->> date - time/iso-date - (get days) - (map orders))}) - -(re-frame/reg-event-db - ::set-current-days - (fn [{start-day :start-date :as db} _] - (->> start-day - time/parse-date - time/start-of-week - (time/days-range 14) - (map (partial get-day db)) - (assoc db :current-days)))) - -(re-frame/reg-event-fx ::process-fetched-days - (fn [{db :db} [_ days]] - (println "fetched days" days) - {:db (-> db - (update :days #(reduce-kv (fn [m k v] (assoc m k (map :id v))) % days)) - (update :orders #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten)))) - :fx [[:dispatch [::set-current-days]] - [:dispatch [::fetch-stock]]]})) - - -(defn missing-days - "Return a map of missing days to be fetched." - [db day] - (let [missing-days (->> day - time/parse-date - time/start-of-week - (time/days-range 28) - (remove (comp (:days db {}) time/iso-date)))] - (when (seq missing-days) - {:from (->> missing-days (sort time/before?) first time/iso-date) - :to (->> missing-days (sort time/before?) last time/iso-date)}))) + (fn [db [_ days]] + (-> db + (update :current-days #(map (fn [[day orders]] + [day (if (contains? days day) + (days day) orders)]) %)) + (update :orders #(reduce (fn [m cust] (assoc m (:id cust) cust)) % (-> days vals flatten)))))) (re-frame/reg-event-fx ::scroll-weeks (fn [{db :db} [_ offset]] - {:dispatch [::show-from-date (-> db :start-date time/parse-date (time/date-offset (* 7 offset)))]})) + {:fx [[:dispatch [::fetch-stock]] + [:dispatch [::show-from-date (-> db + :start-date + time/parse-date + (time/date-offset (* 7 offset)) + time/iso-date)]]]})) + +(re-frame/reg-event-db + ::show-from-date + (fn [{:keys [start-date orders] :as db} [_ day]] + (let [day (or day start-date) + days (into #{} (time/get-weeks day 2)) + filtered-orders (->> orders vals (filter days))] + (assoc db + :start-date day + :current-days (map #(vector % (get filtered-orders %)) days))))) (re-frame/reg-event-fx - ::show-from-date - (fn [{db :db} [_ day]] - (let [missing (missing-days db day) - effects {:db (assoc db :start-date day) - :dispatch [::set-current-days]}] - (if-not missing - effects - (assoc effects :http {:method :get - :url "get-days" - :params missing - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}))))) + ::fetch-orders + (fn [_ [_ from to]] + {(settings :http-dispatch) (http-get "orders" {} ::process-stock)})) + ;; Customers events (re-frame/reg-event-fx ::show-customers @@ -167,11 +131,9 @@ (re-frame/reg-event-fx ::add-customer (fn [_ [_ customer-name]] - {:http {:method :post - :url "add-customer" - :params {:customer-name customer-name} - :on-success [::process-stock] - :on-fail [::failed-blah]}})) + {(settings :http-dispatch) (http-request :post "customers" + :body {:name customer-name} + :on-success ::process-stock)})) ;;; Storage events @@ -184,18 +146,19 @@ (re-frame/reg-event-fx ::fetch-stock (fn [_ _] - {:http {:method :get - :url "get-stock" - :on-success [::process-stock] - :on-fail [::failed-blah]}})) + {(settings :http-dispatch) (http-get "stock" {} ::process-stock)})) -(re-frame/reg-event-db +(defn assoc-if [coll key val] (if val (assoc coll key val) coll)) +(re-frame/reg-event-fx ::process-stock - (fn [db [_ {:keys [products customers]}]] - (println "fetched stock" products) - (assoc db - :products products - :customers customers))) + (fn [{db :db} [_ {:keys [products customers orders]}]] + (prn products customers orders) + {:db (-> db + (assoc-if :products products) + (assoc-if :customers customers) + (assoc-if :orders orders)) + :dispatch [::process-fetched-days (group-by :day (vals orders))] + })) (re-frame/reg-event-db ::update-product-stock @@ -215,13 +178,9 @@ (re-frame/reg-event-fx ::save-stock - (fn [{db :db} [_ products]] + (fn [_ [_ products]] {:dispatch [::hide-modal :stock] - :http {:method :post - :url "save-stock" - :body products - :on-success [::process-fetched-days] - :on-fail [::failed-blah]}})) + (settings :http-dispatch) (http-request :post "products" :body products :on-sucess ::process-stock)})) @@ -236,17 +195,33 @@ (re-frame/reg-fx :http - (fn [{:keys [method url params body on-success on-fail]}] - (condp = url - "get-days" (re-frame/dispatch (conj on-success (mocks/fetch-days params))) - "save-order" (re-frame/dispatch (conj on-success (mocks/replace-order params))) - "delete-order" (re-frame/dispatch (conj on-success (mocks/delete-order params))) - "fulfill-order" (re-frame/dispatch (conj on-success (mocks/order-state (assoc params :state :fulfilled)))) - "reset-order" (re-frame/dispatch (conj on-success (mocks/order-state (assoc params :state :waiting)))) + (fn [{:keys [method uri params body on-success on-fail]}] + (condp = uri + "http://localhost:3000/stock" (re-frame/dispatch (conj on-success (mocks/fetch-stock params))) - "get-stock" (re-frame/dispatch (conj on-success (mocks/fetch-stock params))) "get-customers" (re-frame/dispatch (conj on-success (mocks/fetch-customers params))) "add-customer" (re-frame/dispatch (conj on-success (mocks/add-customer params))) - "get-all-products" (re-frame/dispatch (conj on-success (mocks/get-all-products))) "save-stock" (re-frame/dispatch (conj on-success (mocks/save-stocks body))) + (let [parts (clojure.string/split uri "/")] + (cond + (and (= method :get) (= uri "http://localhost:3000/orders")) + (re-frame/dispatch (conj on-success (mocks/fetch-orders params))) + + (and (= method :post) (= uri "http://localhost:3000/orders")) + (re-frame/dispatch (conj on-success (mocks/replace-order nil (cljs.reader/read-string body)))) + + (and (= method :post) (= uri "http://localhost:3000/products")) + (re-frame/dispatch (conj on-success (mocks/save-stocks (cljs.reader/read-string body)))) + + (= method :delete) + (re-frame/dispatch (conj on-success (mocks/delete-order (-> parts (nth 4) (js/parseInt))))) + + + (and (= method :post) (= uri "http://localhost:3000/customers")) + (re-frame/dispatch (conj on-success (mocks/add-customer (cljs.reader/read-string body)))) + + (-> parts last #{"fulfilled" "waiting"}) + (re-frame/dispatch (conj on-success (mocks/order-state {:id (-> parts (nth 4) (js/parseInt)) :state (keyword (last parts))}))) + true (prn "unhandled" method uri) + )) ))) diff --git a/src/cljs/chicken_master/html.cljs b/src/cljs/chicken_master/html.cljs index 8c3947c..b44a769 100644 --- a/src/cljs/chicken_master/html.cljs +++ b/src/cljs/chicken_master/html.cljs @@ -34,15 +34,16 @@ (defn modal ([modal-id content] - [:div {:class :popup} - [:div {:class :popup-content} + [:div {:class :popup :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} + [:div {:class :popup-content :on-click #(.stopPropagation %)} content [:div {:class :form-buttons} [:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} "ok"]]]]) ([modal-id content on-submit] - [:div {:class :popup} + [:div {:class :popup :on-click #(re-frame/dispatch [::event/hide-modal modal-id])} [:form {:action "#" :class :popup-content + :on-click #(.stopPropagation %) :on-submit (fn [e] (.preventDefault e) (when (-> e .-target form-values on-submit) diff --git a/src/cljs/chicken_master/subs.cljs b/src/cljs/chicken_master/subs.cljs index 85a72b0..d239a83 100644 --- a/src/cljs/chicken_master/subs.cljs +++ b/src/cljs/chicken_master/subs.cljs @@ -10,7 +10,7 @@ (re-frame/reg-sub ::show-stock-modal (fn [db] (-> db :stock :show))) (re-frame/reg-sub ::show-customers-modal (fn [db] (-> db :clients :show))) -(re-frame/reg-sub ::order-edit-who (fn [db] (println (:order-edit db)) (-> db :order-edit :who))) +(re-frame/reg-sub ::order-edit-who (fn [db] (-> db :order-edit :who))) (re-frame/reg-sub ::order-edit-notes (fn [db] (-> db :order-edit :notes))) (re-frame/reg-sub ::order-edit-products (fn [db] (-> db :order-edit :products))) diff --git a/src/cljs/chicken_master/time.cljs b/src/cljs/chicken_master/time.cljs index 7e61dc7..570c1be 100644 --- a/src/cljs/chicken_master/time.cljs +++ b/src/cljs/chicken_master/time.cljs @@ -2,6 +2,8 @@ (:require [chicken-master.config :refer [settings]]) (:import [goog.date DateTime Date Interval])) +(defn today [] (new Date)) + (defn parse-date [date] (new Date (js/Date. date))) (defn date-offset @@ -42,6 +44,13 @@ (defn iso-date [date] (.toIsoString ^js/goog.date.Date date true)) +(defn get-weeks [from n] + (->> from + parse-date + start-of-week + (days-range (* 7 n)) + (map iso-date))) + (comment (with-redefs [settings {:first-day-offset 0}]