From 439f5a254643b0425b7982d9d4df13940d5d6d6e Mon Sep 17 00:00:00 2001
From: Simon Brooke <simon@journeyman.cc>
Date: Wed, 29 Aug 2018 13:55:34 +0100
Subject: [PATCH] I'm almost satisfied; map not scrolling to device location on
 startup

---
 resources/public/css/yyy-common.css           |   2 -
 resources/sql/queries.sql                     |   4 +-
 resources/templates/issue-expert/list.html    |   8 +-
 src/clj/youyesyet/routes/rest.clj             |  12 +-
 src/cljs/youyesyet/canvasser_app/core.cljs    |   4 +-
 src/cljs/youyesyet/canvasser_app/gis.cljs     |  18 +--
 .../youyesyet/canvasser_app/handlers.cljs     |  97 +++++--------
 src/cljs/youyesyet/canvasser_app/state.cljs   | 131 ++----------------
 .../youyesyet/canvasser_app/ui_utils.cljs     |   6 +-
 .../youyesyet/canvasser_app/views/gdpr.cljs   |  31 +++--
 10 files changed, 89 insertions(+), 224 deletions(-)

diff --git a/resources/public/css/yyy-common.css b/resources/public/css/yyy-common.css
index b46e8cb..cbfb6b6 100644
--- a/resources/public/css/yyy-common.css
+++ b/resources/public/css/yyy-common.css
@@ -362,7 +362,6 @@ th {
 
   /* content of the current page in the Wiki - editable, provided by users. Within main-container */
   #content {
-    border: thin solid silver;
     width: 80%;
     float: right;
     padding-bottom: 5em;
@@ -396,7 +395,6 @@ th {
 
   /* content of the current in the Wiki - editable, provided by users. Within main-container */
   #content {
-    border: thin solid silver;
     width: 100%;
     padding-bottom: 2em;
   }
diff --git a/resources/sql/queries.sql b/resources/sql/queries.sql
index 822b2d6..779e572 100644
--- a/resources/sql/queries.sql
+++ b/resources/sql/queries.sql
@@ -43,7 +43,7 @@ SELECT DISTINCT request.*,
 	addresses.address ||', '|| addresses.postcode ||', '|| visits.date AS visit_id_expanded,
   request.issue_id as issue_id_expanded,
 	request.method_id AS method_id_expanded,
-  visits.date
+  visits.date AS raised
 FROM followuprequests as request,
   ln_experts_issues_canvassers as expertise,
   canvassers as experts,
@@ -58,7 +58,7 @@ and request.visit_id = visits.id
 and visits.address_id = addresses.id
 and request.issue_id = expertise.issue_id
 and expertise.canvasser_id = :expert
-ORDER BY visits.date desc
+ORDER BY raised
 
 --:name get-last-visit-by-canvasser :? :1
 --:doc returns the most recent visit record of the canvasser with the specified `:id`
diff --git a/resources/templates/issue-expert/list.html b/resources/templates/issue-expert/list.html
index 5050fe0..b6b31fb 100644
--- a/resources/templates/issue-expert/list.html
+++ b/resources/templates/issue-expert/list.html
@@ -39,7 +39,7 @@ Add a new Followuprequest
 Elector
 </th>
 <th>
-Visit
+Raised
 </th>
 <th>
 Issue
@@ -56,7 +56,7 @@ Method
 <input id='elector_id' type='text' name='elector_id' value='{{ params.elector_id }}'/>
 </th>
 <th>
-<input id='visit_id' type='text' name='visit_id' value='{{ params.visit_id }}'/>
+<input id='raised' type='text' name='raised' value='{{ params.raised }}'/>
 </th>
 <th>
 <input id='issue_id' type='text' name='issue_id' value='{{ params.issue_id }}'/>
@@ -78,9 +78,7 @@ Method
 </a>
 </td>
 <td>
-<a href='{{servlet-context}}/form-visits-Visit?id={{ record.visit_id }}'>
-{{ record.visit_id_expanded }}
-</a>
+{{ record.raised}}
 </td>
 <td>
 <a href='{{servlet-context}}/form-issues-Issue?id={{ record.issue_id }}'>
diff --git a/src/clj/youyesyet/routes/rest.clj b/src/clj/youyesyet/routes/rest.clj
index f3358f2..6e948b0 100644
--- a/src/clj/youyesyet/routes/rest.clj
+++ b/src/clj/youyesyet/routes/rest.clj
@@ -170,19 +170,15 @@
   the elector whose `id` is in the params of this `request`."
   [request]
   (let [params (massage-params request)]
-    (if (and (:elector_id request)(:signature request))
+    (log/debug "Update elector signature with params: " params)
         (valid-user-or-forbid
       (with-params-or-error
         (do-or-server-fail
-          (db/create-followuprequest! db/*db* params)
+          (db/update-elector! db/*db* params)
           201)
         params
-        #{:elector_id :signature})
-      request))
-    {:status 400
-     :body
-     (json/write-str
-       "update-elector-signature requires params `id` and `signature`.")}))
+        #{:id :signature})
+      request)))
 
 
 (defroutes rest-routes
diff --git a/src/cljs/youyesyet/canvasser_app/core.cljs b/src/cljs/youyesyet/canvasser_app/core.cljs
index 89493ac..2dbbe2e 100644
--- a/src/cljs/youyesyet/canvasser_app/core.cljs
+++ b/src/cljs/youyesyet/canvasser_app/core.cljs
@@ -137,7 +137,7 @@
 (secretary/defroute "/elector" []
   (ui/log-and-dispatch [:set-active-page :elector]))
 
-(secretary/defroute "/elector/:elector" {elector-id :elector}
+(secretary/defroute "/elector/:elector/:consent" {elector-id :elector}
   (ui/log-and-dispatch [:set-elector-and-page {:elector-id elector-id :page :elector}]))
 
 (secretary/defroute "/elector/:elector/:consent" {elector-id :elector consent :consent}
@@ -189,7 +189,7 @@
 
 (defn init! []
   (rf/dispatch-sync [:initialize-db])
-  (rf/dispatch-sync [:get-current-location])
+  (rf/dispatch [:get-current-location])
   (rf/dispatch [:fetch-locality])
   (rf/dispatch [:fetch-options])
   (rf/dispatch [:fetch-issues])
diff --git a/src/cljs/youyesyet/canvasser_app/gis.cljs b/src/cljs/youyesyet/canvasser_app/gis.cljs
index c1db28b..2c47192 100644
--- a/src/cljs/youyesyet/canvasser_app/gis.cljs
+++ b/src/cljs/youyesyet/canvasser_app/gis.cljs
@@ -7,7 +7,6 @@
             [re-frame.core :refer [dispatch reg-event-db reg-event-fx subscribe]]
             [ajax.core :refer [GET]]
             [ajax.json :refer [json-request-format json-response-format]]
-            [youyesyet.canvasser-app.state :as db]
             [youyesyet.locality :refer [locality]]
             ))
 
@@ -39,19 +38,20 @@
 
 (defn get-current-location []
   "Get the current location from the device, setting it in the database and
-   returning the locality."
+  returning the locality."
   (try
     (if (.-geolocation js/navigator)
       (.getCurrentPosition
         (.-geolocation js/navigator)
         (fn [position]
-          (js/console.log (str "Current location is: "
-                               (.-latitude (.-coords position)) ", "
-                               (.-longitude (.-coords position))))
-          (dispatch [:set-latitude (.-latitude (.-coords position))])
-          (dispatch [:set-longitude (.-longitude (.-coords position))])
-          (locality (.-latitude (.-coords position)) (.-longitude (.-coords position))))))
-      (js/console.log "Geolocation not available")
+          (let [lat (.-latitude (.-coords position))
+                lng (.-longitude (.-coords position))]
+            (js/console.log (str "Current location is: " lat ", " lng))
+            (dispatch [:set-latitude lat])
+            (dispatch [:set-longitude lng])
+            ;; (.panTo @(subscribe [:view]) (.latLng js/L lat lng))
+            (locality lat lng))))
+      (js/console.log "Geolocation not available"))
     (catch js/Object any
       (js/console.log "Exception while trying to access location: " + any)
       0)))
diff --git a/src/cljs/youyesyet/canvasser_app/handlers.cljs b/src/cljs/youyesyet/canvasser_app/handlers.cljs
index c8d3feb..8c853d5 100644
--- a/src/cljs/youyesyet/canvasser_app/handlers.cljs
+++ b/src/cljs/youyesyet/canvasser_app/handlers.cljs
@@ -140,34 +140,6 @@
     db/default-db))
 
 
-;; (reg-event-fx
-;;   :feedback
-;;   (fn [x y]
-;;     (js/console.log (str "Feedback event called with x = " x "; y = " y))
-;;     (:db x)))
-
-
-;; (reg-event-fx
-;;   :issues
-;;   (fn [x y]
-;;     (js/console.log (str "Issues event called with x = " x "; y = " y))
-;;     (:db x)))
-
-
-;; (reg-event-fx
-;;   :options
-;;   (fn [x y]
-;;     (js/console.log (str "Options event called with x = " x "; y = " y))
-;;     (:db x)))
-
-
-;; (reg-event-fx
-;;   :event
-;;   (fn [x y]
-;;     (js/console.log (str "Event event called with x = " x "; y = " y))
-;;     (:db x)))
-
-
 (reg-event-fx
  :fetch-locality
  (fn [{db :db} _]
@@ -204,38 +176,29 @@
 
 
 (reg-event-fx
- :process-locality
- (fn
-   [{db :db} [_ response]]
-   (js/console.log (str "Updating locality data: " (count response) " addresses " ))
-   (refresh-map-pins)
-   {
-;;      :dispatch-later [{:ms 60000 :dispatch [:fetch-locality]}
-;;                      ;; {:ms 1000 :dispatch [:get-current-location]}
-;;                      ]
-    :db (assoc
-          (remove-from-feedback db :fetch-locality)
-          :addresses (js->clj response))}))
+  :process-locality
+  ;; TODO: why is this an `-fx`? Does it need to be?
+  (fn
+    [{db :db} [_ response]]
+    (js/console.log (str "Updating locality data: " (count response) " addresses " ))
+    (refresh-map-pins)
+    {:db (assoc
+           (remove-from-feedback db :fetch-locality)
+           :addresses (js->clj response))}))
 
 
 (reg-event-fx
   :bad-locality
+  ;; TODO: why is this an `-fx`? Does it need to be?
   (fn
     [{db :db} [_ response]]
     ;; TODO: signal something has failed? It doesn't matter very much, unless it keeps failing.
     (js/console.log "Failed to fetch locality data")
     ;; loop to do it again
     (dispatch [:dispatch-later [{:ms 60000 :dispatch [:fetch-locality]}]])
-    (assoc
+    {:db (assoc
       (remove-from-feedback db :fetch-locality)
-      :error (cons :fetch-locality (:error db)))))
-
-
-;; (reg-event-fx
-;;  :process-outqueue
-;;  (fn [{db :db} _]
-;;    (if
-;;      (empty? (:outqueue db))
+      :error (cons :fetch-locality (:error db)))}))
 
 
 (reg-event-fx
@@ -264,12 +227,12 @@
 
 
 (reg-event-db
- ;; TODO: should try again
   :bad-options
   (fn [db [_ response]]
     (js/console.log "Failed to fetch options")
+    (dispatch [:dispatch-later [{:ms 60000 :dispatch [:fetch-options]}]])
     (assoc
-      (remove-from-feedback db :fetch-options)
+      db
       :error (:response response))))
 
 
@@ -303,12 +266,12 @@
 
 
 (reg-event-db
- ;; TODO: should try again
   :bad-issues
   (fn [db [_ response]]
     (js/console.log "Failed to fetch issues")
+    (dispatch [:dispatch-later [{:ms 60000 :dispatch [:fetch-issues]}]])
     (assoc
-      (remove-from-feedback db :fetch-issues)
+      db
       :error (:response response))))
 
 
@@ -349,7 +312,7 @@
              :method_detail (-> db :method_detail)
              :action :create-request})
           :send-request))
-      (assoc db :error "Please supply a telephone number to call"))))
+      (assoc db :error "Please supply a telephone number/email address for elector"))))
 
 
 (reg-event-db
@@ -382,22 +345,34 @@
             :page :building))))))
 
 
+(defn do-update-elector
+  [db elector]
+  (if-not
+    ;; if the signature has changed
+    (= (:signature elector) (:signature (:elector db)))
+    (assoc
+      (add-to-outqueue
+        (clear-messages db)
+        (assoc elector
+          :action :update-elector-signature))
+      :elector elector)
+    (assoc db
+      :elector elector)))
+
+
 (reg-event-db
   :update-elector
   (fn [db [_ elector]]
     (js/console.log (str "Elector is " elector))
-    db
-))
+    (do-update-elector db elector)))
 
 
 (reg-event-db
   :set-consent-and-page
   (fn [db [_ args]]
-    (let [page (:page args)
-          elector (:elector args)
-          new-db (assoc (clear-messages db) :elector elector :page page)]
-      (dispatch [:update-elector {:elector elector}])
-      new-db)))
+    (assoc
+      (do-update-elector db (:elector args))
+      :page (:page args))))
 
 
 (reg-event-db
diff --git a/src/cljs/youyesyet/canvasser_app/state.cljs b/src/cljs/youyesyet/canvasser_app/state.cljs
index cb67e57..dcb7fae 100644
--- a/src/cljs/youyesyet/canvasser_app/state.cljs
+++ b/src/cljs/youyesyet/canvasser_app/state.cljs
@@ -1,6 +1,7 @@
 (ns ^{:doc "Canvasser app client state."
       :author "Simon Brooke"}
-  youyesyet.canvasser-app.state)
+  youyesyet.canvasser-app.state
+  (:require [youyesyet.canvasser-app.gis :as gis]))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;
@@ -28,129 +29,21 @@
 ;;; This is the constructor for the atom in which the state of the user interface is held.
 ;;; The atom gets updated by 'events' registered in handler.cljs, q.v.
 
-(def default-db
-  {
-    :addresses
-    [{:locality 548223905,
-  :address
-  "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF",
-  :phone nil,
-  :postcode "DG7 1RF",
-  :longitude -3.905045374625994,
-  :district_id 1,
-  :dwellings
-  [{:address_id_expanded
-    "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF",
-    :address_id 18,
-    :sub_address "",
-    :id 17,
-    :id_2 17,
-    :address_id_2 18,
-    :sub_address_2 "",
-    :electors
-    [{:email nil,
-      :dwelling_id_2 17,
-      :dwelling_id_expanded
-      "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
-      :intentions
-      [{:locality 548223905,
-        :visit_id_expanded
-        "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, 2018-06-14 20:29:34.721522",
-        :option_id_expanded "Yes",
-        :option_id "Yes",
-        :option_id_2 "Yes",
-        :visit_id_2 1,
-        :elector_id_2 61,
-        :visit_id 1,
-        :elector_id 61,
-        :id 1,
-        :elector_id_expanded nil,
-        :id_2 1}],
-      :phone nil,
-      :phone_2 nil,
-      :gender_expanded "Female",
-      :name "Alice Sutherland",
-      :dwelling_id 17,
-      :id 61,
-      :gender "Female",
-      :gender_2 "Female",
-      :name_2 "Alice Sutherland",
-      :email_2 nil,
-      :id_2 61}
-     {:email nil,
-      :dwelling_id_2 17,
-      :dwelling_id_expanded
-      "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
-      :intentions [],
-      :phone nil,
-      :phone_2 nil,
-      :gender_expanded "Female",
-      :name "Charlie Sutherland",
-      :dwelling_id 17,
-      :id 62,
-      :gender "Female",
-      :gender_2 "Female",
-      :name_2 "Charlie Sutherland",
-      :email_2 nil,
-      :id_2 62}
-     {:email nil,
-      :dwelling_id_2 17,
-      :dwelling_id_expanded
-      "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
-      :intentions [],
-      :phone nil,
-      :phone_2 nil,
-      :gender_expanded "Male",
-      :name "Keith Sutherland",
-      :dwelling_id 17,
-      :id 64,
-      :gender "Male",
-      :gender_2 "Male",
-      :name_2 "Keith Sutherland",
-      :email_2 nil,
-      :id_2 64}
-     {:email nil,
-      :dwelling_id_2 17,
-      :dwelling_id_expanded
-      "HAZELFIELD HOUSE, CASTLE DOUGLAS, DG7 1RF, DG7 1RF, ",
-      :intentions [],
-      :phone nil,
-      :phone_2 nil,
-      :gender_expanded "Female",
-      :name "Lucy Sutherland",
-      :dwelling_id 17,
-      :id 63,
-      :gender "Female",
-      :gender_2 "Female",
-      :name_2 "Lucy Sutherland",
-      :email_2 nil,
-      :id_2 63}]}],
-  :id 18,
-  :latitude 54.8222716877376}]
 
-    ;;; the currently selected address, if any.
-    :address nil
-    ;;; electors at the currently selected dwelling
-    :electors nil
-    ;;; any error to display
-    :error nil
-    ;;; the issue from among the issues which is currently selected.
-    ;;; any confirmation message to display
-    :feedback '()
-    ;;; the currently selected issue
-    :issue nil
-    ;;; the issues selected for the issues page on this day.
-    :issues nil
+(def default-db
+  { ;;; any confirmation message to display
+    :feedback '("Welcome to the canvasser app!")
     ;;; 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 nil
-    ;;; the queue of items waiting to be transmitted.
-    :outqueue ()
+    :outqueue '()
+    ;;; the view of the map we display
+    :view nil
     ;;; the currently displayed page within the app.
     :page :home
-    :view nil
-    :latitude 54.82
-    :longitude -3.92
+    ;;; initial starting coords in the centre of Scotland.
+    :latitude 56
+    :longitude -4
     :zoom 12})
 
+
diff --git a/src/cljs/youyesyet/canvasser_app/ui_utils.cljs b/src/cljs/youyesyet/canvasser_app/ui_utils.cljs
index 452801a..6609e35 100644
--- a/src/cljs/youyesyet/canvasser_app/ui_utils.cljs
+++ b/src/cljs/youyesyet/canvasser_app/ui_utils.cljs
@@ -45,16 +45,14 @@
 
 (defn big-link
   [text & {:keys [target handler]}]
-  (js/console.log (str "Big link with target '" target "'; onclick handler '" handler "'"))
   [:div.big-link-container {:key (gensym "big-link")}
-   [:a.big-link (merge {:alt "Hello"}
+   [:a.big-link (merge {}
                   (if target {:href target}{})
-                  (if handler {:title handler}{}))
+                  (if handler {:on-click handler}{}))
     text]])
 
 
 (defn nav-link [uri title page collapsed?]
-  (js/console.log (str "Adding nav-link with title '" title "'; target '" uri "'"))
   (let [selected-page @(rf/subscribe [:page])]
     [:li.nav-item
      {:class (when (= page selected-page) "active")
diff --git a/src/cljs/youyesyet/canvasser_app/views/gdpr.cljs b/src/cljs/youyesyet/canvasser_app/views/gdpr.cljs
index 6011ab6..4100a33 100644
--- a/src/cljs/youyesyet/canvasser_app/views/gdpr.cljs
+++ b/src/cljs/youyesyet/canvasser_app/views/gdpr.cljs
@@ -35,6 +35,22 @@
   (atom nil))
 
 
+(defn send-consent
+  "Extract the signature from the signature pad, encode it, add it to this
+  `elector`, and dispatch the `elector`; move on to the page `elector`."
+  [elector]
+  (dispatch
+    [:set-consent-and-page
+     {:elector-id (:id elector)
+      :page :elector
+      :elector (assoc
+                 elector
+                 :signature
+                 (.toDataURL
+                   @sig-pad
+                   "image/svg+xml"))}])
+  nil)
+
 (defn gdpr-render
   []
   (let [elector @(subscribe [:elector])]
@@ -53,20 +69,11 @@
                only against your electoral district, and not link it to you"]]]]
         [:tr
          [:td
-          [:canvas {:id "signature-pad"}]]]]]]
+          [:canvas {:id "signature-pad" :on-mouse-out #(send-consent elector)}]]]]]]
      (ui/back-link "#dwelling")
      (ui/big-link "I consent"
-                  :handler #(dispatch
-                                [:set-consent-and-page
-                                 {:elector-id (:id elector)
-                                  :page :elector
-                                  :elector (assoc
-                                             elector
-                                             :signature
-                                             (.toDataURL
-                                               @sig-pad
-                                               "image/svg+xml")
-                                             )}]))
+                  :target (str "#elector")
+                  :handler #(send-consent elector))
      (ui/big-link "I DO NOT consent"
                   :target (str "#elector/" (:id elector) "/false"))]))