Skip to content

Commit

Permalink
clinic: make views purer
Browse files Browse the repository at this point in the history
  • Loading branch information
ashutoshgngwr committed Oct 27, 2023
1 parent 15e77ad commit 395ceed
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 88 deletions.
23 changes: 18 additions & 5 deletions clinic/src/cljs/clinic/router.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,25 @@
(defn start! []
(pushy/start! history))

(defn replace-token! [token]
(pushy/replace-token! history token))
(rf/reg-event-fx ::set-current-view
(fn [{db :db} [_ view-id params]]
{:db (assoc db ::current-view {::id view-id ::params params})
:dispatch [::on-current-view-changed]}))

(defn set-token! [token]
(pushy/set-token! history token))
(rf/reg-sub ::current-view get-in)

(rf/reg-fx ::set-token
(fn router-set-token-effect [token]
(set-token! token)))
(pushy/set-token! history token)))

(rf/reg-fx ::replace-token
(fn router-replace-token-effect [token]
(pushy/replace-token! history token)))

(rf/reg-event-fx ::set-token
(fn [_ [_ token]]
{::set-token token}))

(rf/reg-event-fx ::replace-token
(fn [_ [_ token]]
{::replace-token token}))
46 changes: 22 additions & 24 deletions clinic/src/cljs/clinic/views/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,34 @@
[clinic.views.view-patient :as view-patient]
[re-frame.core :as rf]))

(def ^:private views {::router/home home/root
::router/create-patient create-patient/root
::router/view-patient view-patient/root
::router/search-patients list-patients/root})

(def ^:private titles {::router/home "Home"
::router/create-patient "Add Patient"
::router/view-patient "Patient Info"
::router/search-patients "Search Patients"})

(rf/reg-fx ::set-window-title
(fn [title]
(set! (.-title js/document)
(-> title
(or "Page Not Found")
(str " - Acme Clinic")))))

(rf/reg-event-fx ::router/set-current-view
(fn [{db :db} [_ view-id params]]
{:db (assoc db ::current-view {::id view-id ::params params})
::set-window-title (titles view-id)}))

(rf/reg-sub ::current-view :-> ::current-view)
(rf/reg-event-fx ::router/on-current-view-changed
(fn [{db :db} _]
(let [{view-id ::router/id
params ::router/params} (::router/current-view db)]
(case view-id
::router/home {::set-window-title "Home"}
::router/create-patient {::set-window-title "Add Patient"}
::router/view-patient {::set-window-title "Patient Info"
:dispatch [::view-patient/fetch-patient params]}
::router/search-patients {::set-window-title "Search Patients"
:dispatch [::list-patients/fetch-patients params]}))))

(defn root []
(let [current-role (user-role/get)
current-view (rf/subscribe [::current-view])]
(fn []
[components/page {:logout-enabled @current-role
:on-logout-click #(do (user-role/clear)
(router/replace-token! "/"))}
[(get views (::id @current-view) not-found/root)
(::params @current-view)]])))
(let [current-role @(user-role/get)
current-view-id @(rf/subscribe [::router/current-view ::router/id])]
[components/page {:logout-enabled current-role
:on-logout-click #(do (user-role/clear)
(rf/dispatch [::router/replace-token "/"]))}
[(case current-view-id
::router/home home/root
::router/create-patient create-patient/root
::router/view-patient view-patient/root
::router/search-patients list-patients/root
not-found/root)]]))
80 changes: 41 additions & 39 deletions clinic/src/cljs/clinic/views/list_patients.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,55 @@
[reagent.core :as r]))

(rf/reg-event-db ::fetch-patients-success
(fn [db [_ phone page result]]
(assoc-in db [::patients phone page] {::loading false
::data result})))
(fn [db [_ result]]
(assoc db ::patients {::loading false ::data result})))

(rf/reg-event-db ::fetch-patients-failure
(fn [db [_ phone page {error-code :status}]]
(assoc-in db [::patients phone page] {::loading false
::error-code error-code})))
(fn [db [_ {error-code :status}]]
(assoc db ::patients {::loading false ::error-code error-code})))

(rf/reg-event-fx ::fetch-patients
(fn [{db :db} [_ phone page]]
{:db (assoc-in db [::patients phone page] {::loading true})
:http-xhrio {:method :get
:uri (str "/api/v1/patients/")
:params (cond-> {:count 10
:offset (* 10 (dec page))}
phone (assoc :phone phone))
:response-format (ajax/json-response-format {:keywords? true})
:on-success [::fetch-patients-success phone page]
:on-failure [::fetch-patients-failure phone page]}}))
(fn [{db :db} [_ {:keys [phone page] :or {page "1"}}]]
(let [page-num (parse-long page)]
{:db (assoc db ::patients {::loading true})
:http-xhrio {:method :get
:uri (str "/api/v1/patients/")
:params (cond-> {:count 10
:offset (* 10 (dec page-num))}
phone (assoc :phone phone))
:response-format (ajax/json-response-format {:keywords? true})
:on-success [::fetch-patients-success]
:on-failure [::fetch-patients-failure]}})))

(rf/reg-sub ::patients get-in)

(defn- patient-row []
(let [{:keys [index patient]} (r/props (r/current-component))]
[:tr {:class [(if (odd? index) "bg-gray-50" "bg-white")
"hover:bg-gray-100" "hover:cursor-pointer"]
:on-click #(router/set-token! (str "/patients/" (:id patient)))}
:on-click #(rf/dispatch [::router/set-token
(str "/patients/" (:id patient))])}
[:td {:class ["px-6" "py-2"]} (inc index)]
[:td {:class ["px-6" "py-2"]} (:first-name patient) " " (:last-name patient)]
[:td {:class ["px-6" "py-2"]} (:birth-date patient)]
[:td {:class ["px-6" "py-2"]} (:phone patient)]]))

(defn root []
(let [props (r/props (r/current-component))
page (parse-long (get props :page "1"))
phone (:phone props)
loading? (rf/subscribe [::patients phone page ::loading])
patients (rf/subscribe [::patients phone page ::data])
error-code (rf/subscribe [::patients phone page ::error-code])]
(rf/dispatch [::fetch-patients phone page])
(let [params @(rf/subscribe [::router/current-view ::router/params])
page (parse-long (get params :page "1"))
phone (:phone params)
loading? @(rf/subscribe [::patients ::loading])
patients @(rf/subscribe [::patients ::data])
error-code @(rf/subscribe [::patients ::error-code])]
[:section {:class ["flex" "flex-col" "gap-8"]}
[:div {:class ["flex" "flex-row" "self-center" "items-center" "gap-6"]}
[:form {:class ["flex" "flex-row" "self-center" "items-center" "gap-6"]
;; TODO: better way to handle submission of this GET form.
:on-submit #(do (.preventDefault %)
(rf/dispatch [::router/set-token
(-> js/document
(.getElementById "phone")
(.-value)
((partial str "/patients?phone=")))]))}
[:input {:id "phone"
:name "phone"
:placeholder "Search by phone"
Expand All @@ -58,26 +64,22 @@
"rounded" "py-2.5" "px-4" "leading-tight"
"focus:outline-none" "focus:bg-white"
"focus:border-gray-500"]}]
[:button {:class ["bg-blue-600" "hover:bg-blue-800" "text-white"
"font-bold" "py-2" "px-4" "rounded-full"]
:on-click #(-> js/document
(.getElementById "phone")
(.-value)
((partial str "/patients?phone="))
(router/set-token!))}
"Search"]]
[:input {:type "submit"
:value "Search"
:class ["bg-blue-600" "hover:bg-blue-800" "text-white"
"font-bold" "py-2" "px-4" "rounded-full"]}]]

(cond
@loading?
loading?
[components/spinner {:class ["block" "self-center" "w-8" "h-8" "m-16" "text-blue-600"]}]

@error-code
error-code
[components/danger-alert "There was an error while fetching patient data. Please try again!"]

(empty? @patients)
(empty? patients)
[:p {:class ["self-center" "text-center"]} "No patients found matching this criteria!"]

@patients
patients
[:<>
[:table {:class ["w-full" "table-auto" "self-center" "text-center"]}
[:thead
Expand All @@ -88,7 +90,7 @@
[:th {:class ["px-6" "py-2"]} "Phone Number"]]]
(into [:tbody] (map-indexed #(do [patient-row {:index %1
:patient %2}])
@patients))]
patients))]
[:div {:class ["flex" "flex-row" "justify-center" "gap-8"]}
[:a {:class ["text-blue-600" "hover:underline"
(when (<= page 1) "invisible")]
Expand All @@ -97,7 +99,7 @@
"Prev"]
[:p {:class ["font-medium"]} "Page" " " page]
[:a {:class ["text-blue-600" "hover:underline"
(when (< (count @patients) 10) "invisible")]
(when (< (count patients) 10) "invisible")]
:href (cond-> (str "/patients?page=" (inc page))
phone (str "&phone=" phone))}
"Next"]]])]))
30 changes: 10 additions & 20 deletions clinic/src/cljs/clinic/views/view_patient.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,21 @@


(rf/reg-event-db ::fetch-patient-success
(fn [db [_ patient-id result]]
(assoc-in db
[::patient patient-id]
{::loading false
::data result})))
(fn [db [_ result]]
(assoc db ::patient {::loading false ::data result})))

(rf/reg-event-db ::fetch-patient-failure
(fn [db [_ patient-id {error-code :status}]]
(assoc-in db
[::patient patient-id]
{::loading false
::error-code error-code})))
(fn [db [_ {error-code :status}]]
(assoc db ::patient {::loading false ::error-code error-code})))

(rf/reg-event-fx ::fetch-patient
(fn [{db :db} [_ patient-id]]
(fn [{db :db} [_ {patient-id :id}]]
{:db (assoc-in db [::patient patient-id] {::loading true})
:http-xhrio {:method :get
:uri (str "/api/v1/patients/" patient-id)
:response-format (ajax/json-response-format {:keywords? true})
:on-success [::fetch-patient-success patient-id]
:on-failure [::fetch-patient-failure patient-id]}}))
:on-success [::fetch-patient-success]
:on-failure [::fetch-patient-failure]}}))

(rf/reg-sub ::patient get-in)

Expand Down Expand Up @@ -57,13 +51,9 @@
"Unknown"))

(defn root []
(let [patient-id (-> (r/current-component)
(r/props)
(:id))
loading? @(rf/subscribe [::patient patient-id ::loading])
patient @(rf/subscribe [::patient patient-id ::data])
error-code @(rf/subscribe [::patient patient-id ::error-code])]
(rf/dispatch [::fetch-patient patient-id])
(let [loading? @(rf/subscribe [::patient ::loading])
patient @(rf/subscribe [::patient ::data])
error-code @(rf/subscribe [::patient ::error-code])]
[:section {:class ["flex" "flex-col"]}
(cond
loading? [components/spinner {:class ["block" "self-center" "w-8" "h-8" "m-16" "text-blue-600"]}]
Expand Down

0 comments on commit 395ceed

Please sign in to comment.