(ns com.biffweb.my-project.app (:require [clojure.pprint :as pprint] [clojure.pprint :as pp] [clojure.string :as str] [com.biffweb :as biff] [com.biffweb.my-project.middleware :refer [wrap-session]] [com.biffweb.my-project.settings :as settings] [com.biffweb.my-project.ui :as ui] [honey.sql :as sql] [next.jdbc :as jdbc] [org.sqids.clojure :as sqids])) (defn reset [_] {:status 200 :headers {"HX-Redirect" "/"} :session {}}) ;; thanks https://stackoverflow.com/a/58098360 (def sqids (sqids/sqids {:alphabet "cdefhjknprtvwxy2345689"})) (defn game-code [] (apply str (take 6 (sqids/encode sqids [(rand-int Integer/MAX_VALUE)])))) (defn error-style [s] [:h4.pico-color-red-500 s]) (defn set-bar [{:keys [example/ds session params] :as _ctx}] (let [players (map str/trim (-> params :players str/split-lines))] (if (> 2 (count players)) (error-style "Need at least two players") (let [id (-> session :id) code (game-code) random-order? (= "on" (-> params :random-player-order)) player-order (if random-order? (shuffle (range 0 (count players))) (range 0 (count players)))] (println players) (println player-order) (println (interleave players player-order)) (jdbc/execute! ds (sql/format {:insert-into :game :values [{:id id :code code :display_session id :active false}] :on-conflict :id :do-update-set [:code :display_session :active]})) (jdbc/execute! ds (sql/format {:insert-into :player :values (for [[p o] (partition 2 (interleave players player-order))] {:score 0 :name p :play_order o :game_code code})})) {:status 200 :headers {"HX-redirect" "/game"} :session {:id id}})))) (defn game [{:keys [session params] :example/keys [ds] :as _ctx}] (let [id (:id session) _ (println id) _ (println (str id)) game (jdbc/execute-one! ds (sql/format {:select :* :from :game :where [:= :id id]})) players (sort-by :player/play_order (jdbc/execute! ds (sql/format {:select :* :from :player :where [:= :game_code (:game/code game)]})))] (println id) (pprint/pprint game) (ui/page {} [:div [:nav [:ul [:li [:strong "Score the pigs"]]] [:ul [:li (biff/form {:id "reset" :hx-get "/reset"} [:button.secondary "Reset"])]]] [:h4 id] [:div [:h4 "Game code is " (:game/code game)] [:table [:thead [:tr [:th {:scope "col"} "Player"] [:th {:scope "col"} "Score"]]] (into [:tbody] (for [p players] [:tr [:th {:scope "row"} (:player/name p)] [:td (:player/score p)]]))]]]))) (defn control-view [{:keys [session params path-params] :example/keys [ds] :as _ctx}] (let [code (:code path-params) players (sort-by :player/play_order (jdbc/execute! ds (sql/format {:select :* :from :player :where [:= :game_code code]})))] (ui/page {} [:div [:nav [:ul [:li [:strong "Score the pigs"]]] [:ul [:li (biff/form {:id "reset" :hx-get "/reset"} [:button.secondary "Reset"])]]] [:h5 (str "Game " code)] [:table [:thead [:tr [:th {:scope "col"} "Player"] [:th {:scope "col"} "Score"]]] (into [:tbody] (for [p players] [:tr [:th {:scope "row"} (:player/name p)] [:td (:player/score p)]]))]]))) (defn connect [{:keys [session params] :example/keys [ds] :as _ctx}] (let [code (:game-code params) game (delay (jdbc/execute-one! ds (sql/format {:select :* :from :game :where [:= :code code]})))] (println params) (if (and code @game) {:status 200 :session session :headers {"HX-Redirect" (str "/game/" code)}} (error-style "Code does not exist.")))) (defn app [{:keys [session params] :example/keys [ds] :as _ctx}] (let [id (:id session)] (ui/page {} [:div [:nav [:ul [:li [:strong "Score the pigs"]]] [:ul [:li (biff/form {:id "reset" :hx-get "/reset"} [:button.secondary "Reset"])]]] [:h4 id] [:section [:button {:_ "on click toggle the *display of #new-game-form"} "New game"]] (biff/form {:hx-post "/set-bar" :style {:display :none} :hx-swap "afterend" :id ::new-game-form} [:div [:textarea#players {:type "textarea" :rows "8" :name "players"}] [:fieldset [:legend "Game options:"] [:label [:input {:type "checkbox", :name "random-player-order", :checked ""}] "Random player order"] ;; [:label ;; [:input {:type "checkbox", :name "french", :checked ""}] ;; "French"] ] [:button {:type "submit"} "Start"]]) (biff/form {:hx-post "/connect" :hx-swap "afterend" :id ::connect-to-game} [:fieldset {:role "group"} [:input {:name "game-code", :type "text", :placeholder "Connect to an existing game"}] [:input {:type "submit", :value "Connect"}]])]))) (def about-page (ui/page {:base/title (str "About " settings/app-name)} [:p "This app was made with " [:a {:href "https://biffweb.com"} "Biff"] "."])) (defn echo [{:keys [params]}] {:status 200 :headers {"content-type" "application/json"} :body params}) (def module {:static {"/about/" about-page} :routes ["/" {:middleware [wrap-session]} ["" {:get app}] ["game/" ["" {:get game}] [":code" {:get control-view}]] ["connect" {:post connect}] ["reset" {:get reset}] ["set-bar" {:post set-bar}]] :api-routes [["/api/echo" {:post echo}]]})