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 -Visit +Raised Issue @@ -56,7 +56,7 @@ Method - + @@ -78,9 +78,7 @@ Method - -{{ record.visit_id_expanded }} - +{{ record.raised}} 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"))]))