From b175121101c110b75f978c02e01f4d16ddbf1074 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sun, 26 Dec 2021 11:51:45 -0500 Subject: feat(grfn/bbbg): Style event list Change-Id: I917e11e453126246c4110a6e42452dda4713b441 Reviewed-on: https://cl.tvl.fyi/c/depot/+/4667 Reviewed-by: grfn Autosubmit: grfn Tested-by: BuildkiteCI --- users/grfn/bbbg/src/bbbg/db.clj | 11 ++- users/grfn/bbbg/src/bbbg/db/event.clj | 13 ++- users/grfn/bbbg/src/bbbg/handlers/events.clj | 121 ++++++++++++++++++--------- users/grfn/bbbg/src/bbbg/styles.clj | 15 ++++ users/grfn/bbbg/src/bbbg/util/display.clj | 8 +- 5 files changed, 124 insertions(+), 44 deletions(-) (limited to 'users') diff --git a/users/grfn/bbbg/src/bbbg/db.clj b/users/grfn/bbbg/src/bbbg/db.clj index 3ac3d962cb..a775574b7a 100644 --- a/users/grfn/bbbg/src/bbbg/db.clj +++ b/users/grfn/bbbg/src/bbbg/db.clj @@ -1,6 +1,6 @@ (ns bbbg.db (:gen-class) - (:refer-clojure :exclude [get list]) + (:refer-clojure :exclude [get list count]) (:require [camel-snake-kebab.core :as csk :refer [->kebab-case ->snake_case]] [bbbg.util.core :as u] [clojure.set :as set] @@ -293,13 +293,18 @@ sql-map-or-table) (merge jdbc-opts opts))))) +(defn count + [db sql-map] + (binding [*meta-db* db] + (:count + (fetch db {:select [[:%count.* :count]], :from [[sql-map :sq]]})))) + (defn exists? "Returns true if the given sql query-map would return any results" [db sql-map] (binding [*meta-db* db] (pos? - (:count - (fetch db {:select [[:%count.* :count]], :from [[sql-map :sq]]}))))) + (count db sql-map)))) (defn execute! "Given a database and a honeysql query map, perform an operation on the diff --git a/users/grfn/bbbg/src/bbbg/db/event.clj b/users/grfn/bbbg/src/bbbg/db/event.clj index 41716499db..5e93691dfa 100644 --- a/users/grfn/bbbg/src/bbbg/db/event.clj +++ b/users/grfn/bbbg/src/bbbg/db/event.clj @@ -4,7 +4,8 @@ [bbbg.db :as db] [bbbg.event :as event] [bbbg.util.sql :refer [count-where]] - [honeysql.helpers :refer [merge-group-by merge-left-join merge-select]] + [honeysql.helpers + :refer [merge-group-by merge-left-join merge-select merge-where]] [java-time :refer [local-date]])) (defn create! [db event] @@ -32,6 +33,16 @@ ([] (on-day (local-date))) ([db] (db/list db (today)))) +(defn upcoming + ([] (upcoming {:select [:event.*] :from [:event]})) + ([query] + (merge-where query [:>= :date (local-date)]))) + +(defn past + ([] (past {:select [:event.*] :from [:event]})) + ([query] + (merge-where query [:< :date (local-date)]))) + (defn with-attendee-counts [query] (-> query diff --git a/users/grfn/bbbg/src/bbbg/handlers/events.clj b/users/grfn/bbbg/src/bbbg/handlers/events.clj index 6fe5b8727b..ff34d7f9e6 100644 --- a/users/grfn/bbbg/src/bbbg/handlers/events.clj +++ b/users/grfn/bbbg/src/bbbg/handlers/events.clj @@ -3,26 +3,64 @@ [bbbg.db :as db] [bbbg.db.event :as db.event] [bbbg.event :as event] - [bbbg.handlers.core :refer [authenticated? page-response]] + [bbbg.handlers.core :refer [*authenticated?* page-response]] [bbbg.meetup.import :refer [import-attendees!]] - [bbbg.util.display :refer [format-date]] + [bbbg.util.display :refer [format-date pluralize]] [bbbg.util.time :as t] [bbbg.views.flash :as flash] [compojure.coercions :refer [as-uuid]] [compojure.core :refer [context GET POST]] [java-time :refer [local-date]] - [ring.util.response :refer [not-found redirect]])) + [ring.util.response :refer [not-found redirect]]) + (:import + java.time.format.FormatStyle)) -(defn events-index [{:keys [events authenticated?]}] - [:div - (when authenticated? - [:a {:href "/events/new"} +(defn- num-attendees [event] + (str + (:num-attendees event) + (if (= (t/->LocalDate (::event/date event)) + (local-date)) + " Signed In" + (str " Attendee" (when-not (= 1 (:num-attendees event)) "s"))))) + +(def index-type->label + {:upcoming "Upcoming" + :past "Past"}) +(def other-index-type + {:upcoming :past + :past :upcoming}) + +(defn events-index + [{:keys [events num-events type]}] + [:div.page + [:div.page-header + [:h1 + (pluralize + num-events + (str (index-type->label type) " Event"))] + [:a {:href (str "/events" + (when (= :upcoming type) + "/past"))} + "View " + (index-type->label (other-index-type type)) + " Events"]] + (when *authenticated?* + [:a.button {:href "/events/new"} "Create New Event"]) [:ul.events-list - (for [event events] + (for [event (sort-by + ::event/date + (comp - compare) + events)] [:li - [:a {:href (str "/events/" (::event/id event))} - (format-date (::event/date event))]])]]) + [:p + [:a {:href (str "/events/" (::event/id event))} + (format-date (::event/date event) + FormatStyle/FULL)]] + [:p + (pluralize (:num-rsvps event) "RSVP") + ", " + (num-attendees event)]])]]) (defn- import-attendee-list-form-group [] [:div.form-group @@ -41,19 +79,15 @@ :value "Import"}]]]) (defn event-page [{:keys [event]}] - [:div.event-page - [:h1 (format-date (::event/date event))] - [:div.stats - [:p (:num-rsvps event) " RSVP" - (when-not (= 1 (:num-rsvps event)) "s")] - [:p (:num-attendees event) - (if (= (t/->LocalDate (::event/date event)) - (local-date)) - " Signed In" - (str " Attendee" (when-not (= 1 (:num-attendees event)) "s")))]] - [:div + [:div.page + [:div.page-header + [:h1 (format-date (::event/date event) + FormatStyle/FULL)] [:a {:href (str "/signup-forms/" (::event/id event) )} "Go to Signup Form"]] + [:div.stats + [:p (pluralize (:num-rsvps event) "RSVP")] + [:p (num-attendees event)]] [:div (import-attendees-form event)]]) @@ -65,27 +99,36 @@ (defn event-form ([] (event-form {})) ([event] - [:form {:method "POST" - :action "/events" - :enctype "multipart/form-data"} - [:div.form-group - [:label "Date" - [:input {:type "date" - :id "date" - :name "date" - :value (str (::event/date event))}]]] - (import-attendee-list-form-group) - [:div.form-group - [:input {:type "submit" - :value "Create Event"}]]])) + [:div.page + [:form {:method "POST" + :action "/events" + :enctype "multipart/form-data"} + [:div.form-group + [:label "Date" + [:input {:type "date" + :id "date" + :name "date" + :value (str (::event/date event))}]]] + (import-attendee-list-form-group) + [:div.form-group + [:input {:type "submit" + :value "Create Event"}]]]])) + +(defn- events-list-handler [db query type] + (let [events (db/list db (db.event/with-stats query)) + num-events (db/count db query)] + (page-response + (events-index {:events events + :num-events num-events + :type type})))) (defn events-routes [{:keys [db]}] (context "/events" [] - (GET "/" request - (let [events (db/list db :event)] - (page-response - (events-index {:events events - :authenticated? (authenticated? request)})))) + (GET "/" [] + (events-list-handler db (db.event/upcoming) :upcoming)) + + (GET "/past" [] + (events-list-handler db (db.event/past) :past)) (GET "/new" [date] (page-response diff --git a/users/grfn/bbbg/src/bbbg/styles.clj b/users/grfn/bbbg/src/bbbg/styles.clj index 026fb500cc..50d554c02a 100644 --- a/users/grfn/bbbg/src/bbbg/styles.clj +++ b/users/grfn/bbbg/src/bbbg/styles.clj @@ -310,6 +310,13 @@ {:font-weight "bold" :margin-bottom "0.9rem"}])]) +(defstyles events + [:.events-list + {:margin-top "1rem"} + + [:li + {:margin-bottom "1rem"}]]) + (defstyles styles forms tables @@ -320,6 +327,7 @@ home-page signup-page attendees + events [:body {:color black}] @@ -340,6 +348,13 @@ :margin-left "auto" :margin-right "auto"})] + [:.page-header + {:display :flex + :flex-wrap :wrap + :padding-bottom "0.7rem" + :margin-bottom "1rem" + :border-bottom [["1px" "solid" silver]]}] + [(attr= "role" "button") {:cursor :pointer}] diff --git a/users/grfn/bbbg/src/bbbg/util/display.clj b/users/grfn/bbbg/src/bbbg/util/display.clj index 79bd980887..40716632a3 100644 --- a/users/grfn/bbbg/src/bbbg/util/display.clj +++ b/users/grfn/bbbg/src/bbbg/util/display.clj @@ -10,8 +10,14 @@ (let [formatter (DateTimeFormatter/ofLocalizedDate format-style)] (.format (t/->LocalDate d) formatter)))) +(defn pluralize + ([n sing plur] + (str (or n 0) " " (if (= 1 n) sing plur))) + ([n sing] + (pluralize n sing (str sing "s")))) + (comment (format-date #inst "2021-12-19T05:00:00.000-00:00") (format-date #inst "2021-12-19T05:00:00.000-00:00" - FormatStyle/SHORT) + FormatStyle/FULL) ) -- cgit 1.4.1