-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reagent SPA Maths Pension Age BMI Calculator
- Loading branch information
0 parents
commit 30af8f3
Showing
6 changed files
with
385 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/resources/public/js/compiled/** | ||
figwheel_server.log | ||
pom.xml | ||
*jar | ||
/lib/ | ||
/classes/ | ||
/out/ | ||
/target/ | ||
.lein-deps-sum | ||
.lein-repl-history | ||
.lein-plugins/ | ||
.repl | ||
.nrepl-port |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# simplecalculator | ||
|
||
FIXME: Write a one-line description of your library/project. | ||
|
||
## Overview | ||
|
||
FIXME: Write a paragraph about the library/project and highlight its goals. | ||
|
||
## Setup | ||
|
||
To get an interactive development environment run: | ||
|
||
lein figwheel | ||
|
||
and open your browser at [localhost:3449](http://localhost:3449/). | ||
This will auto compile and send all changes to the browser without the | ||
need to reload. After the compilation process is complete, you will | ||
get a Browser Connected REPL. An easy way to try it is: | ||
|
||
(js/alert "Am I connected?") | ||
|
||
and you should see an alert in the browser window. | ||
|
||
To clean all compiled files: | ||
|
||
lein clean | ||
|
||
To create a production build run: | ||
|
||
lein cljsbuild once min | ||
|
||
And open your browser in `resources/public/index.html`. You will not | ||
get live reloading, nor a REPL. | ||
|
||
## License | ||
|
||
Copyright © 2014 FIXME | ||
|
||
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
(defproject simplecalculator "0.1.0-SNAPSHOT" | ||
:description "FIXME: write this!" | ||
:url "http://example.com/FIXME" | ||
:license {:name "Eclipse Public License" | ||
:url "http://www.eclipse.org/legal/epl-v10.html"} | ||
|
||
:dependencies [[org.clojure/clojure "1.7.0"] | ||
[org.clojure/clojurescript "1.7.170"] | ||
[org.clojure/core.async "0.2.374"] | ||
[reagent "0.5.1" | ||
:exclusions [org.clojure/tools.reader]] | ||
[reagent-forms "0.5.13"] | ||
[reagent-utils "0.1.7"] | ||
[secretary "1.2.3"] | ||
[cljs-pikaday "0.1.2"] | ||
[com.andrewmcveigh/cljs-time "0.3.14"] | ||
[venantius/accountant "0.1.6" | ||
:exclusions [org.clojure/tools.reader]] | ||
|
||
] | ||
|
||
:plugins [[lein-cljsbuild "1.1.1"] | ||
[lein-figwheel "0.5.0-1"]] | ||
|
||
:source-paths ["src"] | ||
|
||
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] | ||
|
||
:cljsbuild {:builds | ||
[{:id "dev" | ||
:source-paths ["src"] | ||
|
||
:figwheel {:on-jsload "simplecalculator.core/on-js-reload"} | ||
|
||
:compiler {:main simplecalculator.core | ||
:asset-path "js/compiled/out" | ||
:output-to "resources/public/js/compiled/simplecalculator.js" | ||
:output-dir "resources/public/js/compiled/out" | ||
:source-map-timestamp true}} | ||
;; This next build is an compressed minified build for | ||
;; production. You can build this with: | ||
;; lein cljsbuild once min | ||
{:id "min" | ||
:source-paths ["src"] | ||
:compiler {:output-to "resources/public/js/compiled/simplecalculator.js" | ||
:main simplecalculator.core | ||
:optimizations :advanced | ||
:pretty-print false}}]} | ||
|
||
:figwheel {;; :http-server-root "public" ;; default and assumes "resources" | ||
;; :server-port 3449 ;; default | ||
;; :server-ip "127.0.0.1" | ||
|
||
:css-dirs ["resources/public/css"] ;; watch and update CSS | ||
|
||
;; Start an nREPL server into the running figwheel process | ||
;; :nrepl-port 7888 | ||
|
||
;; Server Ring Handler (optional) | ||
;; if you want to embed a ring handler into the figwheel http-kit | ||
;; server, this is for simple ring servers, if this | ||
;; doesn't work for you just run your own server :) | ||
;; :ring-handler hello_world.server/handler | ||
|
||
;; To be able to open files in your editor from the heads up display | ||
;; you will need to put a script on your path. | ||
;; that script will have to take a file path and a line number | ||
;; ie. in ~/bin/myfile-opener | ||
;; #! /bin/sh | ||
;; emacsclient -n +$2 $1 | ||
;; | ||
;; :open-file-command "myfile-opener" | ||
|
||
;; if you want to disable the REPL | ||
;; :repl false | ||
|
||
;; to configure a different figwheel logfile path | ||
;; :server-logfile "tmp/logs/figwheel-logfile.log" | ||
}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/* some style */ | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<link href="css/style.css" rel="stylesheet" type="text/css"> | ||
</head> | ||
<body> | ||
<p>dfgh</p> | ||
<div id="app"> | ||
</div> | ||
<script src="js/compiled/simplecalculator.js" type="text/javascript"></script> | ||
|
||
</body> | ||
</html> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
(ns simplecalculator.core | ||
(:require [reagent.core :as r :refer [atom]] | ||
[reagent.session :as session] | ||
[secretary.core :as secretary :include-macros true] | ||
[accountant.core :as accountant] | ||
|
||
)) | ||
|
||
(enable-console-print!) | ||
|
||
;;pension age calculator | ||
(defonce pension-age (r/atom {:dob nil :pensiondate 0 :age 0})) | ||
|
||
(def today (js/Date.)) | ||
|
||
|
||
(defn- before [date days] | ||
;; "Return a new js/Date which is the given number of days before the given date" | ||
(js/Date. (.getFullYear date) (.getMonth date) (- (.getDate date) days))) | ||
|
||
(defn date? [x] | ||
(= (type x) js/Date)) | ||
|
||
|
||
(defn days-between [x y] | ||
;; "Return the number of days between the two js/Date instances" | ||
(when (every? date? [x y]) | ||
(let [ms-per-day (* 1000 60 60 25) | ||
x-ms (.getTime x) | ||
y-ms (.getTime y)] | ||
(.round js/Math (.abs js/Math (/ (- x-ms y-ms) ms-per-day))))) | ||
) | ||
|
||
|
||
(defn get-date! [date] | ||
(if (date? date) | ||
(.toLocaleDateString date "en" "%d-%b-%Y") | ||
"unselected")) | ||
|
||
(defn calc-pensionage [] | ||
(let [{:keys [dob pensiondate age]} @pension-age ] | ||
(if(and (<(js/Date. "1950-04-06") dob) (> (js/Date. "1953-04-05") dob)) | ||
;;age to get state pension is 63 | ||
;;add 63 to dob | ||
((swap! pension-age assoc :age 63) | ||
(swap! pension-age assoc :pensiondate (js/Date. (+ (.getFullYear dob) 63) (.getMonth dob) (.getDate dob))))) | ||
(if(and (<(js/Date. "1953-04-06") dob ) (>(js/Date. "1953-12-05") dob)) | ||
;;age to get state pension is 65 | ||
;;add 65 to dob | ||
((swap! pension-age assoc :age 65) | ||
(swap! pension-age assoc :pensiondate (js/Date. (+ (.getFullYear dob) 65) (.getMonth dob) (.getDate dob))))) | ||
(if(and (<(js/Date. "1953-12-06") dob ) (>(js/Date. "1960-04-05") dob)) | ||
;;age to get state pension is 66 | ||
;;add 66 to dob | ||
((swap! pension-age assoc :age 66) | ||
(swap! pension-age assoc :pensiondate (js/Date. (+ (.getFullYear dob) 66) (.getMonth dob) (.getDate dob)))) | ||
) | ||
(if(and (<(js/Date. "1960-04-06") dob ) (>(js/Date. "1977-04-05") dob)) | ||
;;age to get state pension is 67 | ||
;;add 67 to dob | ||
((swap! pension-age assoc :age 67) | ||
(swap! pension-age assoc :pensiondate (js/Date. (+ (.getFullYear dob) 67) (.getMonth dob) (.getDate dob)))) | ||
) | ||
(if(<(js/Date. "1977-04-06") dob ) | ||
;;age to get state pension is 68 | ||
;;add 68 to dob | ||
((swap! pension-age assoc :age 68) | ||
(swap! pension-age assoc :pensiondate (js/Date. (+ (.getFullYear dob) 68) (.getMonth dob) (.getDate dob)))) | ||
) | ||
) | ||
) | ||
|
||
|
||
;;calculator component | ||
(defonce result-data (r/atom {:number 0 :result nil :operator nil})) | ||
|
||
(defn calc-result [] | ||
(let [{:keys [number result operator]} @result-data] | ||
(if (= operator "+") (swap! result-data assoc :result (+ (* 1 result) (* 1 number)))) | ||
(if (= operator "-") (swap! result-data assoc :result (- result number ))) | ||
(if (= operator "*") (swap! result-data assoc :result (* result number ))) | ||
(if (= operator "/") (swap! result-data assoc :result (/ result number ))) | ||
(swap! result-data assoc :number 0) | ||
)) | ||
|
||
;;BMI Calculator components | ||
(defonce bmi-data (r/atom {:height 180 :weight 80})) | ||
|
||
(defn calc-bmi [] | ||
(let [{:keys [height weight bmi] :as data} @bmi-data | ||
h (/ height 100)] | ||
(if (nil? bmi) | ||
(assoc data :bmi (/ weight (* h h))) | ||
(assoc data :weight (* bmi h h))))) | ||
|
||
(defn slider [param value min max] | ||
[:input {:type "range" :value value :min min :max max | ||
:style {:width "100%"} | ||
:on-change (fn [e] | ||
(swap! bmi-data assoc param (.-target.value e)) | ||
(when (not= param :bmi) | ||
(swap! bmi-data assoc :bmi nil)))}]) | ||
|
||
;; ------------------------- | ||
;; Views | ||
|
||
;;navigation view | ||
;;navigation-view will be shared by three main components | ||
(defn navigation-view [] | ||
[:div | ||
[:a {:href "/"} "Maths "] | ||
[:a {:href "/BMI"} " BMI"] | ||
[:a {:href "/Pensionage"} " PensionAge"] | ||
] | ||
) | ||
|
||
|
||
(defn home-page [] | ||
(let [{:keys [number result operator]} @result-data] | ||
[:div [:h3 "Welcome to calculators"] | ||
[navigation-view] | ||
[:p] | ||
[:input {:type "number" | ||
:value number | ||
:on-change (fn [e] | ||
(swap! result-data assoc :number (.-target.value e)) | ||
) | ||
}] | ||
[:div | ||
[:input {:type "button" | ||
:value "+" | ||
:on-click (fn [e] | ||
(swap! result-data assoc :operator (.-target.value e)) | ||
(if(nil? result) | ||
((swap! result-data assoc :result number) | ||
(swap! result-data assoc :number 0))) | ||
) | ||
}] | ||
[:input {:type "button" | ||
:value "-" | ||
:on-click (fn [e] | ||
(swap! result-data assoc :operator (.-target.value e)) | ||
(if(nil? result) | ||
((swap! result-data assoc :result number) | ||
(swap! result-data assoc :number 0))) | ||
) | ||
}] | ||
[:input {:type "button" | ||
:value "/" | ||
:on-click (fn [e] | ||
(swap! result-data assoc :operator (.-target.value e)) | ||
(if(nil? result) | ||
((swap! result-data assoc :result number) | ||
(swap! result-data assoc :number 0))) | ||
) | ||
}] | ||
[:input {:type "button" | ||
:value "*" | ||
:on-click (fn [e] | ||
(swap! result-data assoc :operator (.-target.value e)) | ||
(if(nil? result) | ||
((swap! result-data assoc :result number) | ||
(swap! result-data assoc :number 0))) | ||
) | ||
}] | ||
[:input {:type "button" | ||
:value "=" | ||
:on-click calc-result | ||
}] | ||
] | ||
[:p result] | ||
|
||
])) | ||
|
||
(defn bmi-page [] | ||
(let [{:keys [weight height bmi]} (calc-bmi) | ||
[color diagnose] (cond | ||
(< bmi 18.5) ["orange" "underweight"] | ||
(< bmi 25) ["inherit" "normal"] | ||
(< bmi 30) ["orange" "overweight"] | ||
:else ["red" "obese"])] | ||
[:div | ||
[navigation-view] | ||
[:h4 "BMI calculator"] | ||
[:div | ||
"Height: " (int height) "cm" | ||
[slider :height height 100 220]] | ||
[:div | ||
"Weight: " (int weight) "kg" | ||
[slider :weight weight 30 150]] | ||
[:div | ||
"BMI: " (int bmi) " " | ||
[:span {:style {:color color}} diagnose] | ||
[slider :bmi bmi 10 50]]])) | ||
|
||
(defn pension-page [] | ||
(let [{:keys [dob pensiondate age]} @pension-age] | ||
[:div | ||
[navigation-view] | ||
[:div [:h2 "State Pension Age Calculator"] | ||
[:h4 "Enter Date Of Birth"] | ||
[:input {:type "date" | ||
:on-change (fn [e] (swap! pension-age assoc :dob (js/Date. (.-target.value e)))) | ||
}] | ||
[:input {:type "button" | ||
:value "Pension Age" | ||
:on-click calc-pensionage | ||
}] | ||
[:p "You will reach pension age at " age " as from " (get-date! pensiondate) ] | ||
] | ||
] | ||
)) | ||
|
||
(defn current-page [] | ||
[:div [(session/get :current-page)]]) | ||
|
||
;; ------------------------- | ||
;; Routes | ||
|
||
(secretary/defroute "/" [] | ||
(session/put! :current-page #'home-page)) | ||
|
||
(secretary/defroute "/BMI" [] | ||
(session/put! :current-page #'bmi-page)) | ||
|
||
(secretary/defroute "/Pensionage" [] | ||
(session/put! :current-page #'pension-page)) | ||
;; ------------------------- | ||
;; Initialize app | ||
|
||
(defn mount-root [] | ||
(r/render [current-page] (.getElementById js/document "app"))) | ||
|
||
|
||
(accountant/configure-navigation!) | ||
(accountant/dispatch-current!) | ||
(mount-root) |