feat(grfn/bbbg): Add an attendees list

Add a list of attendees visible only to authenticated users, with stats
about rsvps, events attended, and no-shows.

Change-Id: Ib9a0fe8acf8c616fb725c613494b37121a1ad0e4
Reviewed-on: https://cl.tvl.fyi/c/depot/+/4501
Reviewed-by: grfn <grfn@gws.fyi>
Autosubmit: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
This commit is contained in:
Griffin Smith 2021-12-19 12:21:46 -05:00 committed by clbot
parent eea2dbadd0
commit 9af35bd683
5 changed files with 73 additions and 1 deletions

View file

@ -2,3 +2,11 @@
(:require [clojure.spec.alpha :as s]))
(s/def ::id uuid?)
(s/def ::meetup-name string?)
(s/def ::discord-name (s/nilable string?))
(s/def ::meetup-user-id (s/nilable string?))
(s/def ::organizer-notes string?)

View file

@ -1,8 +1,12 @@
(ns bbbg.db.attendee
(:require
[bbbg.attendee :as attendee]
[bbbg.db :as db]
[bbbg.util.sql :refer [count-where]]
honeysql-postgres.helpers
[honeysql.helpers :refer [merge-join merge-where]]))
[honeysql.helpers
:refer
[merge-group-by merge-join merge-left-join merge-select merge-where]]))
(defn search
([query]
@ -23,7 +27,27 @@
(merge-join :event_attendee [:= :attendee.id :event_attendee.attendee_id])
(merge-where [:= :event_attendee.event_id event-id]))))
(defn with-stats
([] (with-stats {:select [:attendee.*]
:from [:attendee]}))
([query]
(-> query
(merge-left-join :event_attendee [:= :attendee.id :event_attendee.attendee_id])
(merge-group-by :attendee.id)
(merge-select
[(count-where :event_attendee.rsvpd_attending) :events-rsvpd]
[(count-where :event_attendee.attended) :events-attended]
[(count-where [:and
:event_attendee.rsvpd_attending
[:not :event_attendee.attended]])
:no-shows]))))
(comment
(def db (:db bbbg.core/system))
(search db "gri")
(db/insert! db :attendee {::attendee/meetup-name "Griffin Smith"
::attendee/discord-name "grfn"
})
(db/list db (with-stats))
)

View file

@ -8,11 +8,42 @@
[cheshire.core :as json]
[compojure.core :refer [GET POST routes]]
[honeysql.helpers :refer [merge-where]]
[bbbg.handlers.core :refer [page-response wrap-auth-required]]
[ring.util.response :refer [content-type redirect response]]
[bbbg.views.flash :as flash]))
(defn- attendees-page [{:keys [attendees]}]
[:div
[:form.search-form {:method :get :action "/attendees"}
[:input {:type "search"
:name "q"}]
[: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"]]]
[:tbody
(for [attendee attendees]
[:tr
[:td (::attendee/meetup-name attendee)]
[:td (::attendee/discord-name attendee)]
[:td (:events-rsvpd attendee)]
[:td (:events-attended attendee)]
[:td (:no-shows attendee)]])]]])
(defn attendees-routes [{:keys [db]}]
(routes
(wrap-auth-required
(routes
(GET "/attendees" []
(let [attendees (db/list db (db.attendee/with-stats))]
(page-response (attendees-page {:attendees attendees}))))))
(GET "/attendees.json" [q event_id attended]
(let [results
(db/list
@ -47,6 +78,7 @@
(comment
(def db (:db bbbg.core/system))
(db/list db :attendee)
(db/list db
(->
(db.attendee/search "gr")

View file

@ -12,6 +12,9 @@
(defn- home-page [{:keys [authenticated?]}]
[:nav.home-nav
[:ul
(when authenticated?
[:li [:a {:href "/attendees"}
"Attendees"]])
[:li [:a {:href "/events"}
"Events"]]
[:li [:a {:href "/signup-forms"}

View file

@ -0,0 +1,5 @@
(ns bbbg.util.sql
(:require [honeysql.core :as hsql]))
(defn count-where [cond]
(hsql/call :count (hsql/call :case cond #sql/raw "1" :else nil)))