about summary refs log tree commit diff
path: root/users/aspen/bbbg/src/bbbg/handlers/attendees.clj
diff options
context:
space:
mode:
Diffstat (limited to 'users/aspen/bbbg/src/bbbg/handlers/attendees.clj')
-rw-r--r--users/aspen/bbbg/src/bbbg/handlers/attendees.clj162
1 files changed, 162 insertions, 0 deletions
diff --git a/users/aspen/bbbg/src/bbbg/handlers/attendees.clj b/users/aspen/bbbg/src/bbbg/handlers/attendees.clj
new file mode 100644
index 000000000000..ce84b88e97c1
--- /dev/null
+++ b/users/aspen/bbbg/src/bbbg/handlers/attendees.clj
@@ -0,0 +1,162 @@
+(ns bbbg.handlers.attendees
+  (:require
+   [bbbg.attendee :as attendee]
+   [bbbg.attendee-check :as attendee-check]
+   [bbbg.db :as db]
+   [bbbg.db.attendee :as db.attendee]
+   [bbbg.db.attendee-check :as db.attendee-check]
+   [bbbg.db.event :as db.event]
+   [bbbg.event :as event]
+   [bbbg.handlers.core :refer [page-response wrap-auth-required]]
+   [bbbg.user :as user]
+   [bbbg.util.display :refer [format-date]]
+   [bbbg.views.flash :as flash]
+   [cheshire.core :as json]
+   [compojure.coercions :refer [as-uuid]]
+   [compojure.core :refer [GET POST routes]]
+   [honeysql.helpers :refer [merge-where]]
+   [ring.util.response :refer [content-type not-found redirect response]])
+  (:import
+   java.util.UUID))
+
+(defn- attendees-page [{:keys [attendees q edit-notes]}]
+  [:div.page
+   [:form.search-form {:method :get :action "/attendees"}
+    [:input.search-input
+     {:type "search"
+      :name "q"
+      :value q
+      :title "Search Attendees"}]
+    [:input {:type "submit"
+             :value "Search Attendees"}]]
+   [:table.attendees
+    [:thead
+     [:tr
+      [:th "Meetup Name"]
+      [:th "Discord Name"]
+      [:th "Events RSVPd"]
+      [:th "Events Attended"]
+      [:th "No-Shows"]
+      [:th "Last Vaccination Check"]
+      [:th "Notes"]]]
+    [:tbody
+     (for [attendee (sort-by
+                     (comp #{edit-notes} ::attendee/id)
+                     (comp - compare)
+                     attendees)
+           :let [id (::attendee/id attendee)]]
+       [:tr
+        [:td.attendee-name (::attendee/meetup-name attendee)]
+        [:td
+         [:label.mobile-label "Discord Name: "]
+         (or (not-empty (::attendee/discord-name attendee))
+             "—")]
+        [:td
+         [:label.mobile-label "Events RSVPd: "]
+         (:events-rsvpd attendee)]
+        [:td
+         [:label.mobile-label "Events Attended: "]
+         (:events-attended attendee)]
+        [:td
+         [:label.mobile-label "No-shows: "]
+         (:no-shows attendee)]
+        [:td
+         [:label.mobile-label "Last Vaccination Check: "]
+         (if-let [last-check (:last-check attendee)]
+           (str "✔️ "(-> last-check
+                        ::attendee-check/checked-at
+                        format-date)
+                ", by "
+                (get-in last-check [:user ::user/username]))
+           (list
+            [:span {:title "Not Checked"}
+             "❌"]
+            " "
+            [:a {:href (str "/attendees/" id "/checks/edit")}
+             "Edit"] ))]
+        (if (= edit-notes id)
+          [:td
+           [:form.organizer-notes {:method :post
+                                   :action (str "/attendees/" id "/notes")}
+            [:div.form-group
+             [:input {:type :text :name "notes"
+                      :value (::attendee/organizer-notes attendee)
+                      :autofocus true}]]
+            [:div.form-group
+             [:input {:type "Submit" :value "Save Notes"}]]]]
+          [:td
+           [:p
+            (::attendee/organizer-notes attendee)]
+           [:p
+            [:a {:href (str "/attendees?edit-notes=" id)}
+             "Edit Notes"]]])])]]])
+
+(defn attendees-routes [{:keys [db]}]
+  (routes
+   (wrap-auth-required
+    (routes
+     (GET "/attendees" [q edit-notes]
+       (let [attendees (db/list db (cond-> (db.attendee/with-stats)
+                                     q (db.attendee/search q)))
+             attendees (db.attendee-check/attendees-with-last-checks
+                        db
+                        attendees)
+             edit-notes (some-> edit-notes UUID/fromString)]
+         (page-response (attendees-page {:attendees attendees
+                                         :q q
+                                         :edit-notes edit-notes}))))
+
+     (POST "/attendees/:id/notes" [id :<< as-uuid notes]
+       (if (seq (db/update! db
+                            :attendee
+                            {::attendee/organizer-notes notes}
+                            [:= :id id]))
+         (-> (redirect "/attendees")
+             (flash/add-flash
+              #:flash{:type :success
+                      :message "Notes updated successfully"}))
+         (not-found "Attendee not found")))))
+
+   (GET "/attendees.json" [q event_id attended]
+     (let [results
+           (db/list
+            db
+            (cond->
+                (if q
+                  (db.attendee/search q)
+                  {:select [:attendee.*] :from [:attendee]})
+                event_id (db.attendee/for-event event_id)
+                (some? attended)
+                (merge-where
+                 (case attended
+                   "true" :attended
+                   "false" [:or [:= :attended nil] [:not :attended]]))))]
+       (-> {:results results}
+           json/generate-string
+           response
+           (content-type "application/json"))))
+
+   (POST "/event_attendees" [event_id attendee_id]
+     (if (and (db/exists? db {:select [:id] :from [:event] :where [:= :id event_id]})
+              (db/exists? db {:select [:id] :from [:attendee] :where [:= :id attendee_id]}))
+       (do
+         (db.event/attended! db {::event/id event_id
+                                 ::attendee/id attendee_id})
+         (-> (redirect (str "/signup-forms/" event_id))
+             (flash/add-flash
+              #:flash{:type :success
+                      :message "Thank you for signing in! Enjoy the event."})))
+       (response "Something went wrong")))))
+
+(comment
+  (def db (:db bbbg.core/system))
+  (db/list db :attendee)
+  (db/list db
+           (->
+            (db.attendee/search "gr")
+            (db.attendee/for-event #uuid "9f4f3eae-3317-41a7-843c-81bcae52aebf")))
+  (honeysql.format/format
+   (->
+    (db.attendee/search "gr")
+    (db.attendee/for-event #uuid "9f4f3eae-3317-41a7-843c-81bcae52aebf")))
+  )