diff --git a/users/grfn/bbbg/src/bbbg/handlers/attendees.clj b/users/grfn/bbbg/src/bbbg/handlers/attendees.clj index ccff28c00..e2a57c7da 100644 --- a/users/grfn/bbbg/src/bbbg/handlers/attendees.clj +++ b/users/grfn/bbbg/src/bbbg/handlers/attendees.clj @@ -8,7 +8,8 @@ [cheshire.core :as json] [compojure.core :refer [GET POST routes]] [honeysql.helpers :refer [merge-where]] - [ring.util.response :refer [content-type redirect response]])) + [ring.util.response :refer [content-type redirect response]] + [bbbg.views.flash :as flash])) (defn attendees-routes [{:keys [db]}] (routes @@ -38,5 +39,20 @@ (db.event/attended! db {::event/id event_id ::attendee/id attendee_id}) (-> (redirect (str "/signup-forms/" event_id)) - (assoc :flash "Thank you for signing in! Enjoy the event."))) + (assoc-in [:session :test] 1) + (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 + (-> + (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"))) + ) diff --git a/users/grfn/bbbg/src/bbbg/handlers/core.clj b/users/grfn/bbbg/src/bbbg/handlers/core.clj index 34ab74553..beadc198d 100644 --- a/users/grfn/bbbg/src/bbbg/handlers/core.clj +++ b/users/grfn/bbbg/src/bbbg/handlers/core.clj @@ -1,5 +1,6 @@ (ns bbbg.handlers.core (:require + [bbbg.views.flash :as flash] [hiccup.core :refer [html]] [ring.util.response :refer [content-type response]])) @@ -7,7 +8,7 @@ (let [[{:keys [title]} body] (if (map? opts) [opts body] - [{} (into [opts] body)])] + [{} (concat [opts] body)])] (html [:html {:lang "en"} [:head @@ -19,7 +20,9 @@ :type "text/css" :href "/main.css"}]] [:body - (into [:div.content] body) + [:div.content + (flash/render-flash) + body] [:script {:src "https://cdnjs.cloudflare.com/ajax/libs/tarekraafat-autocomplete.js/10.2.6/autoComplete.js"}] [:script {:src "/main.js"}]]]))) diff --git a/users/grfn/bbbg/src/bbbg/handlers/events.clj b/users/grfn/bbbg/src/bbbg/handlers/events.clj index f42b7bea2..653c8ab45 100644 --- a/users/grfn/bbbg/src/bbbg/handlers/events.clj +++ b/users/grfn/bbbg/src/bbbg/handlers/events.clj @@ -5,7 +5,8 @@ [bbbg.event :as event] [bbbg.handlers.core :refer [page-response]] [compojure.core :refer [context GET POST]] - [ring.util.response :refer [redirect]])) + [ring.util.response :refer [redirect]] + [bbbg.views.flash :as flash])) (defn events-index [events] [:ul.events-list @@ -41,4 +42,5 @@ (let [event (db.event/create! db {::event/date date})] (-> (str "/signup-forms/" (::event/id event)) redirect - (assoc-in [:flash :message] "Event Created")))))) + (flash/add-flash {:flash/type :success + :flash/message "Event Created"})))))) diff --git a/users/grfn/bbbg/src/bbbg/views/flash.clj b/users/grfn/bbbg/src/bbbg/views/flash.clj new file mode 100644 index 000000000..7fcebd645 --- /dev/null +++ b/users/grfn/bbbg/src/bbbg/views/flash.clj @@ -0,0 +1,33 @@ +(ns bbbg.views.flash + (:require [clojure.spec.alpha :as s])) + +(s/def :flash/type #{:success :error :warning}) +(s/def :flash/message string?) +(s/def ::flash (s/keys :req [:flash/type :flash/message])) +(s/fdef add-flash :args (s/cat :resp map? :flash ::flash) :ret map?) + +;;; + +(def ^:dynamic *flash* nil) + +(defn wrap-page-flash [handler] + (fn + ([request] + (binding [*flash* (:flash request)] + (handler request))) + ([request respond raise] + (binding [*flash* (:flash request)] + (handler request respond raise))))) + +(defn add-flash [resp flash] + (update-in resp [:flash :flash/messages] conj flash)) + +(defn render-flash + ([] (render-flash *flash*)) + ([flash] + (when-some [messages (not-empty (:flash/messages flash))] + [:ul.flash-messages + (for [message messages] + [:li.flash-message + {:class (str "flash-" (-> message :flash/type name))} + (:flash/message message)])]))) diff --git a/users/grfn/bbbg/src/bbbg/web.clj b/users/grfn/bbbg/src/bbbg/web.clj index 4e0566bcc..cbef8d0e5 100644 --- a/users/grfn/bbbg/src/bbbg/web.clj +++ b/users/grfn/bbbg/src/bbbg/web.clj @@ -5,6 +5,8 @@ [bbbg.handlers.home :as home] [bbbg.handlers.signup-form :as signup-form] [bbbg.styles :refer [stylesheet]] + [bbbg.util.core :as u] + [bbbg.views.flash :refer [wrap-page-flash]] [clojure.spec.alpha :as s] [com.stuartsierra.component :as component] [compojure.core :refer [GET routes]] @@ -13,23 +15,44 @@ [ring.middleware.flash :refer [wrap-flash]] [ring.middleware.keyword-params :refer [wrap-keyword-params]] [ring.middleware.params :refer [wrap-params]] - [ring.util.response :refer [content-type response resource-response]])) + [ring.middleware.session :refer [wrap-session]] + [ring.middleware.session.cookie :refer [cookie-store]] + [ring.util.response :refer [content-type resource-response response]]) + (:import + java.util.Base64)) (s/def ::port pos-int?) +(s/def ::cookie-secret + (s/and bytes? #(= 16 (count %)))) + (s/def ::config - (s/keys :req [::port])) + (s/keys :req [::port] + :opt [::cookie-secret])) (s/fdef make-server :args (s/cat :config ::config)) + +(defn- string->cookie-secret [raw] + (s/assert + ::cookie-secret + (when raw + (.decode (Base64/getDecoder) + (.getBytes raw "UTF-8"))))) + (defn env->config [] (s/assert ::config - {::port (:port env 8888)})) + (u/remove-nils + {::port (:port env 8888) + ::cookie-secret (some-> env :cookie-secret string->cookie-secret)}))) (defn dev-config [] - (s/assert ::config {::port 8888})) + (s/assert + ::config + {::port 8888 + ::cookie-secret (into-array Byte/TYPE (repeat 16 0))})) ;;; @@ -47,17 +70,19 @@ (events/events-routes env) (home/home-routes env))) -(defn middleware [app] +(defn middleware [app env] (-> app wrap-keyword-params wrap-params - wrap-flash)) + wrap-page-flash + wrap-flash + (wrap-session {:store (cookie-store {:key (:cookie-secret env)})}))) -(defn handler [this] - (middleware - (app-routes this))) +(defn handler [env] + (-> (app-routes env) + (middleware env))) -(defrecord WebServer [port db] +(defrecord WebServer [port cookie-secret db] component/Lifecycle (start [this] (assoc this @@ -71,7 +96,8 @@ (dissoc this ::shutdown-fn)) this))) -(defn make-server [{::keys [port]}] +(defn make-server [{::keys [port cookie-secret]}] (component/using - (map->WebServer {:port port}) + (map->WebServer {:port port + :cookie-secret cookie-secret}) [:db]))