From 4d566514a9dd77244edeafe45699e1e53f68d6ad Mon Sep 17 00:00:00 2001 From: Daniel O'Connell Date: Sat, 10 Oct 2020 21:06:27 +0200 Subject: [PATCH] dynamic data --- src/cljs/chicken_master/calendar.cljs | 86 ++++++++++----------------- src/cljs/chicken_master/config.cljs | 5 ++ src/cljs/chicken_master/core.cljs | 1 + src/cljs/chicken_master/db.cljs | 29 ++++++++- src/cljs/chicken_master/events.cljs | 31 ++++++++-- src/cljs/chicken_master/html.cljs | 23 +++++++ src/cljs/chicken_master/products.cljs | 20 +++++++ src/cljs/chicken_master/subs.cljs | 20 ++++--- src/cljs/chicken_master/time.cljs | 11 ++-- src/cljs/chicken_master/views.cljs | 12 ++-- 10 files changed, 158 insertions(+), 80 deletions(-) create mode 100644 src/cljs/chicken_master/html.cljs create mode 100644 src/cljs/chicken_master/products.cljs diff --git a/src/cljs/chicken_master/calendar.cljs b/src/cljs/chicken_master/calendar.cljs index e67aaef..42b808d 100644 --- a/src/cljs/chicken_master/calendar.cljs +++ b/src/cljs/chicken_master/calendar.cljs @@ -1,64 +1,43 @@ (ns chicken-master.calendar (:require [re-frame.core :as re-frame] + [chicken-master.config :refer [settings]] [chicken-master.subs :as subs] - [chicken-master.time :as time] - )) + [chicken-master.html :as html] + [chicken-master.products :as prod] + [chicken-master.events :as event] + [chicken-master.time :as time])) -(defn get-day [date] - {:date date - :customers [{:who "mr.blobby (649 234 234)" :when date :products {:eggs 2 :milk 3}} - {:who "da police (0118 999 881 999 119 725 123123 12 3123 123 )" :when date :products {:eggs 12}} - {:who "johnny" :when date :products {:eggs 5}}]}) - - -(defn modal [content on-submit] - [:div {:class :popup} - [:form {:action "#"} - content - [:div {:class :form-buttons} - [:input {:type :submit :value "add"}] - [:button {:type :button} "cancel"]]]]) - -(defn add-product [date order-id] - (modal - [:div - [:div {:class :input-item} - [:label {:for :product} "co"] - [:input {:type :text :name :product :id :product}]] - [:div {:class :input-item} - [:label {:for :amount} "ile"] - [:input {:type :number :name :amount :id :amount}]]] - js/console.log)) (defn add-order [date] - (modal + (html/modal [:div - [:div {:class :input-item} - [:label {:for :who} "kto"] - [:input {:type :text :name :who :id :who :required true :step "60"}]] - [:div {:class :input-item} - [:label {:for :when} "kiedy"] - [:input {:type :time :name :when :id :when}]] - [:div {} - [:label "co"] - ]] + (html/input :who "kto" + {:required true + :default @(re-frame/subscribe [::subs/order-edit-who])}) + (html/input :when "kiedy" + {:type :time :step 60 + :default @(re-frame/subscribe [::subs/order-edit-when])}) + (let [available-prods @(re-frame/subscribe [::subs/available-products]) + selected-prods @(re-frame/subscribe [::subs/order-edit-products])] + [:div {} + [:label "co"] + (for [{product :prod amount :amount} selected-prods] + (prod/product-item product amount available-prods))]) + [:button {:type :button :on-click #(re-frame/dispatch [::event/add-product])} "+"]] js/console.log)) -(defn format-product [[product amount]] - [:li {:class :product} - [:input {:class :product-amount :type :number :min 0 :defaultValue amount}] - [:span {:class :product-name} product]]) - -(defn format-order [{:keys [who when products]}] - [:li {:class :order} +(defn format-order [{:keys [id who when products]}] + [:li {:class :order :key (gensym)} [:div {:class :actions} - [:button "+"] [:button "O"] [:button "-"]] + [:button "O"] + [:button {:on-click #(re-frame/dispatch [::event/edit-order when id])} "E"] + [:button "-"]] [:div {:class :who} who] - (if (subs/settings :show-order-time) + (if (settings :show-order-time) [:div {:class :when} (str (.getHours when) ":" (.getMinutes when))]) (->> products - (map format-product) + (map prod/format-product) (into [:ul {:class :products}]))]) (defn day [{:keys [date customers]}] @@ -67,15 +46,16 @@ [:div [:ul {:class :orders} (map format-order customers) - [:button {:type :button} "+"]]]]) + [:button {:type :button + :on-click #(re-frame/dispatch [::event/edit-order date])} "+"]]]]) (defn calendar-header [] - (->> (subs/settings :day-names) + (->> (settings :day-names) (map (fn [day] [:div {:class :day-header} day])) (into []))) (defn calendar [days] - (->> days - (map (comp day get-day)) - (concat (when-not (subs/settings :always-day-names) (calendar-header))) - (into [:div {:class [:calendar :full-height]}]))) + (->> days + (map day) + (concat (when-not (settings :always-day-names) (calendar-header))) + (into [:div {:class [:calendar :full-height]}]))) diff --git a/src/cljs/chicken_master/config.cljs b/src/cljs/chicken_master/config.cljs index 8da7c1f..1e1c310 100644 --- a/src/cljs/chicken_master/config.cljs +++ b/src/cljs/chicken_master/config.cljs @@ -2,3 +2,8 @@ (def debug? ^boolean goog.DEBUG) + +(def settings {:first-day-offset 1 + :day-names ["Niedz" "Pon" "Wt" "Śr" "Czw" "Pt" "Sob"] + :always-day-names true + :show-order-time false}) diff --git a/src/cljs/chicken_master/core.cljs b/src/cljs/chicken_master/core.cljs index 08cea23..e235e86 100644 --- a/src/cljs/chicken_master/core.cljs +++ b/src/cljs/chicken_master/core.cljs @@ -20,5 +20,6 @@ (defn init [] (re-frame/dispatch-sync [::events/initialize-db]) + (re-frame/dispatch-sync [::events/show-from-date (new js/Date "2020-09-05")]) (dev-setup) (mount-root)) diff --git a/src/cljs/chicken_master/db.cljs b/src/cljs/chicken_master/db.cljs index b0c10ec..c55f31b 100644 --- a/src/cljs/chicken_master/db.cljs +++ b/src/cljs/chicken_master/db.cljs @@ -1,4 +1,31 @@ (ns chicken-master.db) (def default-db - {:name "re-frame"}) + {:name "re-frame" + :order-edit {:show nil + :who "mr. blobby" + :when "12:32" + :products [{:prod :eggs :amount 2} + {:prod :milk :amount 5} + {}]} + :customers {1 {:who "mr.blobby (649 234 234)" :day "2020-10-10" :hour "02:12" :products {:eggs 2 :milk 3}} + 2 {:who "da police (0118 999 881 999 119 725 123123 12 3123 123 )" :day "2020-10-10" :hour "02:12" :products {:eggs 12}} + 3 {:who "johnny" :day "2020-10-10" :hour "02:12" :products {:eggs 5}}} + :days {"2020-09-05" [1 2 3] + "2020-09-06" [1 2 3] + "2020-09-07" [1 2 3] + "2020-09-08" [1 2 3] + "2020-09-09" [1 2 3] + "2020-09-10" [1 2 3] + "2020-09-11" [1 2 3] + "2020-09-12" [1 2 3] + "2020-09-13" [1 2 3] + "2020-09-14" [1 2 3] + "2020-09-15" [1 2 3] + "2020-09-16" [1 2 3] + "2020-09-17" [1 2 3] + "2020-09-18" [1 2 3]} + :products {:eggs {} + :milk {} + :cabbage {} + :carrots {}}}) diff --git a/src/cljs/chicken_master/events.cljs b/src/cljs/chicken_master/events.cljs index 37bb7e8..79375bc 100644 --- a/src/cljs/chicken_master/events.cljs +++ b/src/cljs/chicken_master/events.cljs @@ -2,9 +2,32 @@ (:require [re-frame.core :as re-frame] [chicken-master.db :as db] - )) + [chicken-master.time :as time])) + +(re-frame/reg-event-db ::initialize-db (fn [_ _] db/default-db)) + +(re-frame/reg-event-db ::hide-modal (fn [db _] (assoc db :order-edit {}))) +(re-frame/reg-event-db + ::edit-order + (fn [{customers :customers :as db} [_ date id]] + (assoc db :order-edit (merge (get customers id) + {:show true :day date})))) + +(re-frame/reg-event-db ::add-product (fn [db _] (update-in db [:order-edit :products] conj {}))) + + +(defn get-day [{:keys [days customers]} date] + {:date date + :customers (->> (.toIsoString ^js/goog.date.Date date true) + (get days) + (map customers))}) + (re-frame/reg-event-db - ::initialize-db - (fn [_ _] - db/default-db)) + ::show-from-date + (fn [db [_ date]] + (->> date + time/start-of-week + (time/days-range 14) + (map (partial get-day db)) + (assoc db :current-days)))) diff --git a/src/cljs/chicken_master/html.cljs b/src/cljs/chicken_master/html.cljs new file mode 100644 index 0000000..2b32b36 --- /dev/null +++ b/src/cljs/chicken_master/html.cljs @@ -0,0 +1,23 @@ +(ns chicken-master.html + (:require [re-frame.core :as re-frame] + [chicken-master.events :as event])) + + +(defn input + ([id label] (input id label {})) + ([id label options] + [:div {:class :input-item} + [:label {:for id} label] + [:input (-> options + (assoc :defaultValue (:default options)) + (dissoc :default) + (merge {:name id :id id}))]])) + + +(defn modal [content on-submit] + [:div {:class :popup} + [:form {:action "#" :on-submit on-submit} + content + [:div {:class :form-buttons} + [:button "add"] + [:button {:type :button :on-click #(re-frame/dispatch [::event/hide-modal])} "cancel"]]]]) diff --git a/src/cljs/chicken_master/products.cljs b/src/cljs/chicken_master/products.cljs new file mode 100644 index 0000000..089637a --- /dev/null +++ b/src/cljs/chicken_master/products.cljs @@ -0,0 +1,20 @@ +(ns chicken-master.products + (:require + [re-frame.core :as re-frame] + [chicken-master.html :as html] + [chicken-master.events :as event])) + +(defn product-item [what amount available] + [:div {:key (gensym)} + [:div {:class :input-item} + [:label {:for :product} "co"] + [:select {:name :product :id :product :defaultValue what} + [:option {:value nil} "-"] + (for [product available] + [:option {:key (gensym) :value product} (name product)])]] + (html/input :amount "ile" {:type :number :default amount :min 0})]) + +(defn format-product [[product amount]] + [:li {:key (gensym) :class :product} + [:input {:class :product-amount :type :number :min 0 :defaultValue amount}] + [:span {:class :product-name} product]]) diff --git a/src/cljs/chicken_master/subs.cljs b/src/cljs/chicken_master/subs.cljs index 6ad834c..cee16e4 100644 --- a/src/cljs/chicken_master/subs.cljs +++ b/src/cljs/chicken_master/subs.cljs @@ -1,13 +1,15 @@ (ns chicken-master.subs (:require - [re-frame.core :as re-frame])) + [re-frame.core :as re-frame] + [chicken-master.time :as time])) -(re-frame/reg-sub - ::name - (fn [db] - (:name db))) +(re-frame/reg-sub ::name (fn [db] (:name db))) +(re-frame/reg-sub ::available-products (fn [db] (-> db :products keys))) -(def settings {:first-day-offset 1 - :day-names ["Niedz" "Pon" "Wt" "Śr" "Czw" "Pt" "Sob"] - :always-day-names true - :show-order-time false}) +(re-frame/reg-sub ::show-edit-modal (fn [db] (-> db :order-edit :show))) +(re-frame/reg-sub ::order-edit-who (fn [db] (-> db :order-edit :who))) +(re-frame/reg-sub ::order-edit-when (fn [db] (-> db :order-edit :hour))) +(re-frame/reg-sub ::order-edit-products (fn [db] (-> db :order-edit :products))) + + +(re-frame/reg-sub ::current-days (fn [db] (:current-days db))) diff --git a/src/cljs/chicken_master/time.cljs b/src/cljs/chicken_master/time.cljs index d7ac8e3..e9b7c0a 100644 --- a/src/cljs/chicken_master/time.cljs +++ b/src/cljs/chicken_master/time.cljs @@ -1,12 +1,11 @@ (ns chicken-master.time - (:require - [chicken-master.subs :as subs]) + (:require [chicken-master.config :refer [settings]]) (:import [goog.date DateTime Date Interval])) (defn date-offset "Return the `date` offset by the given number of `days`" [date days] - (let [new-day (new DateTime date)] + (let [new-day (new Date date)] (.add new-day (new Interval Interval/DAYS days)) new-day)) @@ -14,13 +13,13 @@ "Get the start of the week for the given `date" [date] (->> (.getDay date) - (- (subs/settings :first-day-offset)) + (- (settings :first-day-offset)) (date-offset date))) (defn days-range "Return dates starting from `date`" ([date] (map (partial date-offset date) (range))) - ([date n] (take n (days-range date)))) + ([n date] (take n (days-range date)))) (defn same-day? "Returns true when both dates are from the same day" [d1 d2] @@ -31,5 +30,5 @@ (defn format-date [date] (str - (->> date .getDay (nth (subs/settings :day-names))) + (->> date .getDay (nth (settings :day-names))) " " (.getMonth date) "/" (.getDate date))) diff --git a/src/cljs/chicken_master/views.cljs b/src/cljs/chicken_master/views.cljs index 0dafea1..b88aa40 100644 --- a/src/cljs/chicken_master/views.cljs +++ b/src/cljs/chicken_master/views.cljs @@ -3,15 +3,13 @@ [re-frame.core :as re-frame] [chicken-master.subs :as subs] [chicken-master.calendar :as cal] - [chicken-master.time :as time] - )) + [chicken-master.time :as time])) + (defn main-panel [] (let [name (re-frame/subscribe [::subs/name])] [:div {:class :full-height} - (cal/add-order (new js/Date)) - (-> (new js/Date) - time/start-of-week - (time/days-range 14) - cal/calendar) + (when @(re-frame/subscribe [::subs/show-edit-modal]) + (cal/add-order (new js/Date))) + (cal/calendar @(re-frame/subscribe [::subs/current-days])) ]))