Skip to content

Commit

Permalink
Reagent SPA Maths Pension Age BMI Calculator
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Dec 31, 2015
0 parents commit 30af8f3
Show file tree
Hide file tree
Showing 6 changed files with 385 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gitignore
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
39 changes: 39 additions & 0 deletions README.md
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.
79 changes: 79 additions & 0 deletions project.clj
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"
})
2 changes: 2 additions & 0 deletions resources/public/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* some style */

15 changes: 15 additions & 0 deletions resources/public/index.html
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>
237 changes: 237 additions & 0 deletions src/simplecalculator/core.cljs
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)

0 comments on commit 30af8f3

Please sign in to comment.