#36: Followup request doesn't actually send, everything else works

This commit is contained in:
Simon Brooke 2017-03-30 22:15:03 +01:00
parent 4be0b9ce08
commit c75bdb9e5e
8 changed files with 189 additions and 104 deletions

View file

@ -365,6 +365,14 @@ th {
/* phones, and, indeed, smaller phones. Adapted to touch; display radically /* phones, and, indeed, smaller phones. Adapted to touch; display radically
* decluttered */ * decluttered */
@media all and (max-device-width: 768px) { @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 { footer {
display: none; display: none;
} }
@ -375,14 +383,6 @@ th {
padding-left: 75px; 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 { .hidden {
display: none; display: none;
} }

View file

@ -79,7 +79,11 @@
[:div [:div
[:header [:header
[ui/navbar]] [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] (if content [content]
[:div.error (str "No content in page " :page)]))]) [:div.error (str "No content in page " :page)]))])
@ -109,7 +113,7 @@
(rf/dispatch [:set-elector-and-page {:elector-id elector-id :page :issues}])) (rf/dispatch [:set-elector-and-page {:elector-id elector-id :page :issues}]))
(secretary/defroute "/issue/:issue" {issue :issue} (secretary/defroute "/issue/:issue" {issue :issue}
(rf/dispatch [:set-issue issue])) (rf/dispatch [:set-and-go-to-issue issue]))
(secretary/defroute "/map" [] (secretary/defroute "/map" []
(rf/dispatch [:set-active-page :map])) (rf/dispatch [:set-active-page :map]))

View file

@ -31,44 +31,48 @@
(def default-db (def default-db
{;;; the currently selected address, if any. {;;; the currently selected address, if any.
:address {:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2569057 :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} :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no}
{:id 2 :name "Ann Anderson" :gender :female} {:id 2 :name "Ann Anderson" :gender :female}
{:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes}
{:id 4 :name "Andy Anderson" :intention :yes}]} {:id 4 :name "Andy Anderson" :intention :yes}]}
;;; a list of the addresses in the current location at which there ;;; a list of the addresses in the current location at which there
;;; are electors registered. ;;; are electors registered.
:addresses [{:id 1 :address "13 Imaginary Terrace, IM1 3TE" :latitude 55.8253043 :longitude -4.2570944 :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} :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no}
{:id 2 :name "Ann Anderson" :gender :female} {:id 2 :name "Ann Anderson" :gender :female}
{:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes}
{:id 4 :name "Andy Anderson" :intention :yes}]} {:id 4 :name "Andy Anderson" :intention :yes}]}
{:id 2 :address "15 Imaginary Terrace, IM1 3TE" :latitude 55.8252354 :longitude -4.2572778 {:id 2 :address "15 Imaginary Terrace, IM1 3TE" :latitude 55.8252354 :longitude -4.2572778
:electors [{:id 1 :name "Beryl Brown" :gender :female} :electors [{:id 1 :name "Beryl Brown" :gender :female}
{:id 2 :name "Betty Black" :gender :female}]} {:id 2 :name "Betty Black" :gender :female}]}
{:id 3 :address "17 Imaginary Terrace, IM1 3TE" :latitude 55.825166 :longitude -4.257026 {:id 3 :address "17 Imaginary Terrace, IM1 3TE" :latitude 55.825166 :longitude -4.257026
:electors [{:id 1 :name "Catriona Crathie" :gender :female :intention :yes} :electors [{:id 1 :name "Catriona Crathie" :gender :female :intention :yes}
{:id 2 :name "Colin Caruthers" :gender :male :intention :yes} {:id 2 :name "Colin Caruthers" :gender :male :intention :yes}
{:id 3 :name "Calum Crathie" :intention :yes}]} {:id 3 :name "Calum Crathie" :intention :yes}]}
{:id 4 :address "19 Imaginary Terrace, IM1 3TE" :latitude 55.82506950000001 :longitude -4.2570239 {: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 [{:id 1 :name "David Dewar" :gender :male :intention :no}]}]
;;; electors at the currently selected address ;;; electors at the currently selected address
:electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no} :electors [{:id 1 :name "Alan Anderson" :gender :male :intention :no}
{:id 2 :name "Ann Anderson" :gender :female} {:id 2 :name "Ann Anderson" :gender :female}
{:id 3 :name "Alex Anderson" :gender :fluid :intention :yes} {:id 3 :name "Alex Anderson" :gender :fluid :intention :yes}
{:id 4 :name "Andy Anderson" :intention :yes}] {:id 4 :name "Andy Anderson" :intention :yes}]
;;; the issue from among the issues which is currently selected. ;;; any error to display
:issue "Currency" :error nil
;;; the issues selected for the issues page on this day. ;;; the issue from among the issues which is currently selected.
: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" ;;; any confirmation message to display
"Monarchy" "Scotland could keep the Queen. This is an issue to be decided after independence. Yada yada yada" :feedback nil
"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"} ;;; the currently selected issue
;;; message of the day :issue "Currency"
:motd "This is a test version only. There is no real data." ;;; the issues selected for the issues page on this day.
;;; the options from among which electors can select. :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"
:options [{:id :yes :description "Yes"} {:id :no :description "No"}] "Monarchy" "Scotland could keep the Queen. This is an issue to be decided after independence. Yada yada yada"
;;; the number of requests created by the user in the current session "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"}
:requests 0 ;;; message of the day
;;; the currently displayed 'page' within the app. :motd "This is a test version only. There is no real data."
:page :home ;;; 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
})

View file

@ -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 (reg-event-db
:initialize-db :initialize-db
(fn [_ _] (fn [_ _]
db/default-db)) 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 (reg-event-db
:set-active-page :set-active-page
(fn [db [_ page]] (fn [db [_ page]]
(if page (if page
(assoc db :page page)))) (assoc (clear-messages db) :page page))))
(reg-event-db (reg-event-db
@ -45,48 +81,71 @@
(fn [db [_ address-id]] (fn [db [_ address-id]]
(let [id (read-string address-id) (let [id (read-string address-id)
address (first (remove nil? (map #(if (= id (:id %)) %) (:addresses db))))] 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 (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]] (fn [db [_ args]]
(let [page (:page args) (let [intention (:intention args)
elector-id (read-string (:elector-id args)) elector-id (:elector-id args)
elector elector
(first (first
(remove nil? (remove nil?
(map (map
#(if (= elector-id (:id %)) %) #(if (= elector-id (:id %)) %)
(:electors (:address db)))))] (:electors (:address db)))))
(js/console.log (str "Setting page to " page ", elector to " elector)) old-address (:address db)
(assoc (assoc db :elector elector) :page page)))) new-address (assoc old-address :electors (cons (assoc elector :intention intention) (remove #(= % elector) (:electors old-address))))]
(cond
(nil? elector)
(reg-event-db (assoc db :error "No elector found; not setting intention")
:set-intention (= intention (:intention elector)) (do (js/console.log "Elector's intention hasn't changed; not setting intention") db)
(fn [db [_ args]] true
(let [intention (:intention args) (do
elector-id (read-string (:elector-id args)) (js/console.log (str "Setting intention of elector " elector " to " intention))
elector (merge
(first (clear-messages db)
(remove nil? {:addresses
(map (cons new-address (remove old-address (:addresses db)))
#(if (= elector-id (:id %)) %) :address new-address
(:electors (:address db))))) :outqueue (cons (assoc args :action :set-intention) (:outqueue 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)))))))))
(reg-event-db (reg-event-db
:set-issue :set-issue
(fn [db [_ issue]] (fn [db [_ issue]]
(js/console.log (str "Setting page to :issue, issue to " issue)) (js/console.log (str "Setting issue to " issue))
(assoc (assoc db :issue issue) :page :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)))

View file

@ -49,6 +49,16 @@
(fn [db _] (fn [db _]
(:elector db))) (:elector db)))
(reg-sub
:error
(fn [db _]
(:error db)))
(reg-sub
:feedback
(fn [db _]
(:feedback db)))
(reg-sub (reg-sub
:issue :issue
(fn [db _] (fn [db _]

View file

@ -1,6 +1,6 @@
(ns youyesyet.views.electors (ns youyesyet.views.electors
(:require [reagent.core :refer [atom]] (: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])) [youyesyet.ui-utils :as ui]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -71,15 +71,20 @@
[electors option] [electors option]
(let [optid (:id option) (let [optid (:id option)
optname (name optid)] optname (name optid)]
[:tr {:key (str "options-" optid)} [:tr {:key (str "options-" optname)}
(map (map
#(let [selected (= optid (:intention %)) (fn [elector] (let [selected (= optid (:intention elector))
image (if selected (str "img/option/" optname "-selected.png") image (if selected (str "img/option/" optname "-selected.png")
(str "img/option/" optname "-unselected.png"))] (str "img/option/" optname "-unselected.png"))]
[:td {:key (str "option-" optid "-" (:id %))} [:td {:key (str "option-" optid "-" (:id elector))}
[:a {:href (str "#/set-intention/" (:id %) "/" optid)} [:img
[:img {:src image :alt optname}]]]) {:src image
electors)])) :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 (defn issue-cell
@ -102,7 +107,7 @@
[] []
(let [address @(subscribe [:address]) (let [address @(subscribe [:address])
addresses @(subscribe [:addresses]) addresses @(subscribe [:addresses])
electors (:electors address) electors (sort-by :id (:electors address))
options @(subscribe [:options]) options @(subscribe [:options])
changes @(subscribe [:changes])] changes @(subscribe [:changes])]
(if address (if address

View file

@ -1,5 +1,5 @@
(ns youyesyet.views.followup (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])) [youyesyet.ui-utils :as ui]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -50,25 +50,28 @@
[:div [:div
[:h1 "Followup Request"] [:h1 "Followup Request"]
[:div.container {:id "main-container"} [:div.container {:id "main-container"}
[:form {} [:div {}
[:p.widget [:p.widget
[:label {:for "elector"} "Elector"] [: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 (map
#(let [] #(let []
[:option {:value (:id %) :key (:id %)} (:name %)]) (:electors address))]] [:option {:value (:id %) :key (:id %)} (:name %)]) (:electors address))]]
[:p.widget [:p.widget
[:label {:for "issue"} "Issue"] [: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 (map
#(let [] #(let []
[:option {:key % :value %} %]) (keys issues))]] [:option {:key % :value %} %]) (keys issues))]]
[:p.widget [:p.widget
[:label {:for "telephone"} "Telephone number"] [: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 [:p.widget
[:label {:for "submit"} "To request a call"] [:label {:for "send"} "To request a call"]
[:input {:id "submit" :name "submit" :type "submit" :value "Send this!"}]] [:button {:id "send" :on-click #(dispatch [:send-request])} "Send this!"]]]
]
(ui/back-link)]]))) (ui/back-link)]])))

View file

@ -69,7 +69,7 @@
[id] [id]
(js/console.log (str "Click handler for address #" id)) (js/console.log (str "Click handler for address #" id))
(set! window.location.href (str "#electors/" 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 ;; (defn map-pin-click-handler
;; [id] ;; [id]
;; (dispatch [:set-address id])) ;; (dispatch [:set-address id]))