Created
August 4, 2015 19:50
-
-
Save jraines/e234223292c9e8588e2d to your computer and use it in GitHub Desktop.
Attempt to do a kinda sorta redux like app in ClojureScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ^:figwheel-always ramquiz.core | |
(:require [quiescent.core :as q] | |
[quiescent.dom :as d])) | |
(enable-console-print!) | |
(declare render-app) | |
;; the data | |
(defonce questions | |
[{:question "How old are you?" | |
:options [["Less Than 50" 0] ["Older Than 50" 2]]} | |
{:question "Do either of your parents have heart disease?" | |
:options [["Yes" 2] ["No" 0]]} | |
{:question "Do you smoke?" | |
:options [["Yes" 2] ["No" 0]]} | |
{:question "Do you eat red meat more than 5x/week?" | |
:options [["Yes" 2] ["No" 0]]} | |
{:question "Do you drink more than 3x/week?" | |
:options [["Yes" 2] ["No" 0]]} | |
]) | |
;; define your app data so that it doesn't get over-written on reload | |
(defonce app-state (atom {:questions questions | |
:total 0})) | |
(defonce original-state @app-state) | |
;action creators | |
(defn selectedOption [option] | |
{:type "selectedOption" | |
:amount (second option)}) | |
;state change functions | |
(defn incTotal [amount] | |
(partial (fn [a m] | |
(assoc m :total (+ a (:total m)))) amount)) | |
(defn unshift-question [m] | |
(assoc m :questions (vec (rest (:questions m))))) | |
;handle order | |
(defn dispatch [action] | |
(println "dispatching") | |
(condp = (:type action) | |
"selectedOption" (do | |
(swap! app-state (incTotal (:amount action))) | |
(swap! app-state unshift-question)) | |
"reset" (do | |
(reset! app-state original-state)) | |
) | |
(render-app) | |
) | |
;components | |
(q/defcomponent Option | |
[o] | |
(let [answer (first o) | |
updateState (fn [] (dispatch (selectedOption o)))] | |
(d/div {} | |
(d/p {:onClick updateState} answer)))) | |
(q/defcomponent Question | |
[q] | |
(d/div {} | |
(d/h1 {} (:question q)) | |
(apply d/div {} (map Option (:options q))))) | |
(q/defcomponent Total | |
[t] | |
(let [c (condp >= t | |
3 "low" | |
6 "medium" | |
8 "high")] | |
(d/div {:className (str t " " c)} t))) | |
(q/defcomponent Quiz | |
[q state] | |
(let [data (:questions state) | |
total (:total state) | |
totalClass (condp >= total | |
3 "low" | |
6 "medium" | |
8 "high") | |
updateState (fn [] (dispatch {:type "reset"}))] | |
(d/div {:className "quiz"} | |
(Total total) | |
(d/div {:onClick updateState} "Reset") | |
(d/div {} (Question q))))) | |
(q/defcomponent EmptyView | |
[_] | |
(d/div {:className "quiz"} | |
(Total (:total @app-state)) | |
(d/p {} "No more questions!"))) | |
(defn render-app [] | |
(let [q (first (:questions @app-state)) | |
total (:total @app-state)] | |
(if (nil? q) | |
(q/render (EmptyView nil) | |
(.getElementById js/document "root")) | |
(q/render (Quiz q @app-state) | |
(.getElementById js/document "root"))))) | |
(render-app) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment