From c75bdb9e5e4a10dccb0e201c7add72798fc6de1a Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 30 Mar 2017 22:15:03 +0100 Subject: [PATCH] #36: Followup request doesn't actually send, everything else works --- resources/public/css/yyy-common.css | 16 ++-- src/cljs/youyesyet/core.cljs | 8 +- src/cljs/youyesyet/db.cljs | 86 +++++++++-------- src/cljs/youyesyet/handlers.cljs | 127 ++++++++++++++++++------- src/cljs/youyesyet/subscriptions.cljs | 10 ++ src/cljs/youyesyet/views/electors.cljs | 25 +++-- src/cljs/youyesyet/views/followup.cljs | 19 ++-- src/cljs/youyesyet/views/map.cljs | 2 +- 8 files changed, 189 insertions(+), 104 deletions(-) diff --git a/resources/public/css/yyy-common.css b/resources/public/css/yyy-common.css index 465171a..fb06db1 100644 --- a/resources/public/css/yyy-common.css +++ b/resources/public/css/yyy-common.css @@ -365,6 +365,14 @@ th { /* phones, and, indeed, smaller phones. Adapted to touch; display radically * decluttered */ @media all and (max-device-width: 768px) { + button, input, select { + background-color: rgb( 50, 109, 177); + color: white; + font-size: 1.1em; + padding: 0.25em 1em; + border-radius: 0.5em; + } + footer { display: none; } @@ -375,14 +383,6 @@ th { padding-left: 75px; } - input, select { - background-color: rgb( 50, 109, 177); - color: white; - font-size: 1.1em; - padding: 0.25em 1em; - border-radius: 0.5em; - } - .hidden { display: none; } diff --git a/src/cljs/youyesyet/core.cljs b/src/cljs/youyesyet/core.cljs index b7712cb..cffa508 100644 --- a/src/cljs/youyesyet/core.cljs +++ b/src/cljs/youyesyet/core.cljs @@ -79,7 +79,11 @@ [:div [:header [ui/navbar]] - (let [content (pages @(rf/subscribe [:page]))] + (let [content (pages @(rf/subscribe [:page])) + error @(rf/subscribe [:error]) + feedback @(rf/subscribe [:feedback])] + [:div.error {:style (str "display: " (if error "block" "none"))} (str error)] + [:div.feedback {:style (str "display: " (if feedback "block" "none"))} (str feedback)] (if content [content] [:div.error (str "No content in page " :page)]))]) @@ -109,7 +113,7 @@ (rf/dispatch [:set-elector-and-page {:elector-id elector-id :page :issues}])) (secretary/defroute "/issue/:issue" {issue :issue} - (rf/dispatch [:set-issue issue])) + (rf/dispatch [:set-and-go-to-issue issue])) (secretary/defroute "/map" [] (rf/dispatch [:set-active-page :map])) diff --git a/src/cljs/youyesyet/db.cljs b/src/cljs/youyesyet/db.cljs index 45881be..5803072 100644 --- a/src/cljs/youyesyet/db.cljs +++ b/src/cljs/youyesyet/db.cljs @@ -31,44 +31,48 @@ (def default-db {;;; the currently selected address, if any. - :address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2569057 - :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} - {:id 2 :name "Ann Anderson" :gender :female} - {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} - {:id 4 :name "Andy Anderson" :intention :yes}]} - ;;; a list of the addresses in the current location at which there - ;;; are electors registered. - :addresses [{:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2570944 - :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} - {:id 2 :name "Ann Anderson" :gender :female} - {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} - {:id 4 :name "Andy Anderson" :intention :yes}]} - {:id 2 :address "15 Imaginary Terrace, IM1 3TE" :latitude 55.8252354 :longitude -4.2572778 - :electors [{:id 1 :name "Beryl Brown" :gender :female} - {:id 2 :name "Betty Black" :gender :female}]} - {:id 3 :address "17 Imaginary Terrace, IM1 3TE" :latitude 55.825166 :longitude -4.257026 - :electors [{:id 1 :name "Catriona Crathie" :gender :female :intention :yes} - {:id 2 :name "Colin Caruthers" :gender :male :intention :yes} - {:id 3 :name "Calum Crathie" :intention :yes}]} - {:id 4 :address "19 Imaginary Terrace, IM1 3TE" :latitude 55.82506950000001 :longitude -4.2570239 - :electors [{:id 1 :name "David Dewar" :gender :male :intention :no}]}] - ;;; electors at the currently selected address - :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} - {:id 2 :name "Ann Anderson" :gender :female} - {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} - {:id 4 :name "Andy Anderson" :intention :yes}] - ;;; the issue from among the issues which is currently selected. - :issue "Currency" - ;;; the issues selected for the issues page on this day. - :issues {"Currency" "Scotland could keep the Pound, or use the Euro. But we could also set up a new currency of our own. Yada yada yada" - "Monarchy" "Scotland could keep the Queen. This is an issue to be decided after independence. Yada yada yada" - "Defence" "Scotland will not have nuclear weapons, and will probably not choose to engage in far-off wars. But we could remain members of NATO"} - ;;; message of the day - :motd "This is a test version only. There is no real data." - ;;; the options from among which electors can select. - :options [{:id :yes :description "Yes"} {:id :no :description "No"}] - ;;; the number of requests created by the user in the current session - :requests 0 - ;;; the currently displayed 'page' within the app. - :page :home - }) + :address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2569057 + :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} + {:id 2 :name "Ann Anderson" :gender :female} + {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} + {:id 4 :name "Andy Anderson" :intention :yes}]} + ;;; a list of the addresses in the current location at which there + ;;; are electors registered. + :addresses [{:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2570944 + :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} + {:id 2 :name "Ann Anderson" :gender :female} + {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} + {:id 4 :name "Andy Anderson" :intention :yes}]} + {:id 2 :address "15 Imaginary Terrace, IM1 3TE" :latitude 55.8252354 :longitude -4.2572778 + :electors [{:id 1 :name "Beryl Brown" :gender :female} + {:id 2 :name "Betty Black" :gender :female}]} + {:id 3 :address "17 Imaginary Terrace, IM1 3TE" :latitude 55.825166 :longitude -4.257026 + :electors [{:id 1 :name "Catriona Crathie" :gender :female :intention :yes} + {:id 2 :name "Colin Caruthers" :gender :male :intention :yes} + {:id 3 :name "Calum Crathie" :intention :yes}]} + {:id 4 :address "19 Imaginary Terrace, IM1 3TE" :latitude 55.82506950000001 :longitude -4.2570239 + :electors [{:id 1 :name "David Dewar" :gender :male :intention :no}]}] + ;;; electors at the currently selected address + :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} + {:id 2 :name "Ann Anderson" :gender :female} + {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} + {:id 4 :name "Andy Anderson" :intention :yes}] + ;;; any error to display + :error nil + ;;; the issue from among the issues which is currently selected. + ;;; any confirmation message to display + :feedback nil + ;;; the currently selected issue + :issue "Currency" + ;;; the issues selected for the issues page on this day. + :issues {"Currency" "Scotland could keep the Pound, or use the Euro. But we could also set up a new currency of our own. Yada yada yada" + "Monarchy" "Scotland could keep the Queen. This is an issue to be decided after independence. Yada yada yada" + "Defence" "Scotland will not have nuclear weapons, and will probably not choose to engage in far-off wars. But we could remain members of NATO"} + ;;; message of the day + :motd "This is a test version only. There is no real data." + ;;; the options from among which electors can select. + :options [{:id :yes :description "Yes"} {:id :no :description "No"}] + ;;; the currently displayed 'page' within the app. + :outqueue () + :page :home + }) diff --git a/src/cljs/youyesyet/handlers.cljs b/src/cljs/youyesyet/handlers.cljs index 4c9b665..1a3373e 100644 --- a/src/cljs/youyesyet/handlers.cljs +++ b/src/cljs/youyesyet/handlers.cljs @@ -27,17 +27,53 @@ ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defn clear-messages + "Return a state like this state except with the error and feedback messages + set nil" + [state] + (merge state {:error nil :feedback nil})) + + +(defn get-elector + "Return the elector at this address (or the current address if not specified) + with this id." + ([elector-id state] + (get-elector elector-id state (:address state))) + ([elector-id state address] + (first + (remove + nil? + (map + #(if (= elector-id (:id %)) %) + (:electors address)))))) + + (reg-event-db :initialize-db (fn [_ _] db/default-db)) + (reg-event-db + :send-request + (fn [db [_ _]] + (if (and (:elector db) (:issue db) (:telephone db)) + (do + (js/console.log "Sending request") + (assoc db + :feedback "Request has been queued" + :outqueue (cons + {:elector-id (:id (:elector db)) + :issue (:issue db) + :action :add-request} (:outqueue db)))) + (assoc db :error "Please supply a telephone number to call")))) + + (reg-event-db :set-active-page (fn [db [_ page]] (if page - (assoc db :page page)))) + (assoc (clear-messages db) :page page)))) (reg-event-db @@ -45,48 +81,71 @@ (fn [db [_ address-id]] (let [id (read-string address-id) address (first (remove nil? (map #(if (= id (:id %)) %) (:addresses db))))] - (assoc (assoc db :address address) :page :electors)))) + (assoc (clear-messages db) :address address :page :electors)))) (reg-event-db - :set-elector-and-page + :set-and-go-to-issue + (fn [db [_ issue]] + (js/console.log (str "Setting page to :issue, issue to " issue)) + (assoc (assoc (clear-messages db) :issue issue) :page :issue))) + + + (reg-event-db + :set-elector-and-page + (fn [db [_ args]] + (let [page (:page args) + elector-id (read-string (:elector-id args)) + elector (get-elector elector-id db)] + (js/console.log (str "Setting page to " page ", elector to " elector)) + (assoc (clear-messages db) :elector elector :page page)))) + + +(reg-event-db + :set-elector + (fn [db [_ elector-id]] + (let [elector (get-elector (read-string elector-id) db)] + (js/console.log (str "Setting elector to " elector)) + (assoc (clear-messages db) :elector elector)))) + + +(reg-event-db + :set-intention (fn [db [_ args]] - (let [page (:page args) - elector-id (read-string (:elector-id args)) + (let [intention (:intention args) + elector-id (:elector-id args) elector (first (remove nil? - (map - #(if (= elector-id (:id %)) %) - (:electors (:address db)))))] - (js/console.log (str "Setting page to " page ", elector to " elector)) - (assoc (assoc db :elector elector) :page page)))) - - -(reg-event-db - :set-intention - (fn [db [_ args]] - (let [intention (:intention args) - elector-id (read-string (:elector-id args)) - elector - (first - (remove nil? - (map - #(if (= elector-id (:id %)) %) - (:electors (:address db))))) - old-address (:address db) - new-address (assoc old-address :electors (cons (assoc elector :intention intention) (remove #(= % elector) (:electors old-address))))] - (cond - (nil? elector)(do (js/console.log "No elector found; not setting intention") db) - (= intention (:intention elector)) (do (js/console.log "Elector's intention hasn't changed; not setting intention") db) - true - (do - (js/console.log (str "Setting intention of elector " elector " to " intention)) - (assoc db :addresses (cons new-address (remove old-address (:addresses db))))))))) + (map + #(if (= elector-id (:id %)) %) + (:electors (:address db))))) + old-address (:address db) + new-address (assoc old-address :electors (cons (assoc elector :intention intention) (remove #(= % elector) (:electors old-address))))] + (cond + (nil? elector) + (assoc db :error "No elector found; not setting intention") + (= intention (:intention elector)) (do (js/console.log "Elector's intention hasn't changed; not setting intention") db) + true + (do + (js/console.log (str "Setting intention of elector " elector " to " intention)) + (merge + (clear-messages db) + {:addresses + (cons new-address (remove old-address (:addresses db))) + :address new-address + :outqueue (cons (assoc args :action :set-intention) (:outqueue db))})))))) (reg-event-db :set-issue (fn [db [_ issue]] - (js/console.log (str "Setting page to :issue, issue to " issue)) - (assoc (assoc db :issue issue) :page :issue))) + (js/console.log (str "Setting issue to " issue)) + (assoc (clear-messages db) :issue issue))) + + +(reg-event-db + :set-telephone + (fn [db [_ telephone]] + (js/console.log (str "Setting telephone to " telephone)) + (assoc (clear-messages db) :issue telephone))) diff --git a/src/cljs/youyesyet/subscriptions.cljs b/src/cljs/youyesyet/subscriptions.cljs index d6961cf..1a3b6ff 100644 --- a/src/cljs/youyesyet/subscriptions.cljs +++ b/src/cljs/youyesyet/subscriptions.cljs @@ -49,6 +49,16 @@ (fn [db _] (:elector db))) +(reg-sub + :error + (fn [db _] + (:error db))) + +(reg-sub + :feedback + (fn [db _] + (:feedback db))) + (reg-sub :issue (fn [db _] diff --git a/src/cljs/youyesyet/views/electors.cljs b/src/cljs/youyesyet/views/electors.cljs index 15195e4..ef867d0 100644 --- a/src/cljs/youyesyet/views/electors.cljs +++ b/src/cljs/youyesyet/views/electors.cljs @@ -1,6 +1,6 @@ (ns youyesyet.views.electors (:require [reagent.core :refer [atom]] - [re-frame.core :refer [reg-sub subscribe]] + [re-frame.core :refer [reg-sub subscribe dispatch]] [youyesyet.ui-utils :as ui])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -71,15 +71,20 @@ [electors option] (let [optid (:id option) optname (name optid)] - [:tr {:key (str "options-" optid)} + [:tr {:key (str "options-" optname)} (map - #(let [selected (= optid (:intention %)) - image (if selected (str "img/option/" optname "-selected.png") - (str "img/option/" optname "-unselected.png"))] - [:td {:key (str "option-" optid "-" (:id %))} - [:a {:href (str "#/set-intention/" (:id %) "/" optid)} - [:img {:src image :alt optname}]]]) - electors)])) + (fn [elector] (let [selected (= optid (:intention elector)) + image (if selected (str "img/option/" optname "-selected.png") + (str "img/option/" optname "-unselected.png"))] + [:td {:key (str "option-" optid "-" (:id elector))} + [:img + {:src image + :alt optname + :on-click #(dispatch + [:set-intention {:elector-id (:id elector) + :intention optid}])}]])) + ;; TODO: impose an ordering on electors - by name or by id + electors)])) (defn issue-cell @@ -102,7 +107,7 @@ [] (let [address @(subscribe [:address]) addresses @(subscribe [:addresses]) - electors (:electors address) + electors (sort-by :id (:electors address)) options @(subscribe [:options]) changes @(subscribe [:changes])] (if address diff --git a/src/cljs/youyesyet/views/followup.cljs b/src/cljs/youyesyet/views/followup.cljs index bfa6a0f..78c0c04 100644 --- a/src/cljs/youyesyet/views/followup.cljs +++ b/src/cljs/youyesyet/views/followup.cljs @@ -1,5 +1,5 @@ (ns youyesyet.views.followup - (:require [re-frame.core :refer [reg-sub subscribe]] + (:require [re-frame.core :refer [reg-sub subscribe dispatch]] [youyesyet.ui-utils :as ui])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -50,25 +50,28 @@ [:div [:h1 "Followup Request"] [:div.container {:id "main-container"} - [:form {} + [:div {} [:p.widget [:label {:for "elector"} "Elector"] - [:select {:id "elector" :name "elector" :value (:id elector)} + [:select {:id "elector" :name "elector" :defaultValue (:id elector) + :on-change #(dispatch [:set-elector (.-value (.-target %))])} (map #(let [] [:option {:value (:id %) :key (:id %)} (:name %)]) (:electors address))]] [:p.widget [:label {:for "issue"} "Issue"] - [:select {:id "issue" :name "issue" :value issue} + ;; #(reset! val (-> % .-target .-value)) + [:select {:id "issue" :name "issue" :defaultValue issue + :on-change #(dispatch [:set-issue (.-value (.-target %))])} (map #(let [] [:option {:key % :value %} %]) (keys issues))]] [:p.widget [:label {:for "telephone"} "Telephone number"] - [:input {:type "text" :id "telephone" :name "telephone"}]] + [:input {:type "text" :id "telephone" :name "telephone" + :on-change #(dispatch [:set-telephone (.-value (.-target %))])}]] [:p.widget - [:label {:for "submit"} "To request a call"] - [:input {:id "submit" :name "submit" :type "submit" :value "Send this!"}]] - ] + [:label {:for "send"} "To request a call"] + [:button {:id "send" :on-click #(dispatch [:send-request])} "Send this!"]]] (ui/back-link)]]))) diff --git a/src/cljs/youyesyet/views/map.cljs b/src/cljs/youyesyet/views/map.cljs index 01bae13..c725531 100644 --- a/src/cljs/youyesyet/views/map.cljs +++ b/src/cljs/youyesyet/views/map.cljs @@ -69,7 +69,7 @@ [id] (js/console.log (str "Click handler for address #" id)) (set! window.location.href (str "#electors/" id))) -;; This way is probably more idiomatic React, but back links don't work: +;; This way is probably more idiomatic React, but history doesn't work: ;; (defn map-pin-click-handler ;; [id] ;; (dispatch [:set-address id]))