mirror of
https://github.com/mruwnik/chicken-master.git
synced 2025-06-08 21:34:43 +02:00
Calendar view
This commit is contained in:
commit
d637579eff
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/out/
|
||||
/resources/public/js/compiled/
|
||||
/target/
|
||||
/*-init.clj
|
||||
/*.log
|
||||
|
||||
# Leiningen
|
||||
/.lein-*
|
||||
/.nrepl-port
|
||||
|
||||
# Node.js dependencies
|
||||
/node_modules/
|
||||
|
||||
# shadow-cljs cache, port files
|
||||
/shadow-cljs.edn
|
||||
/.shadow-cljs/
|
268
README.md
Normal file
268
README.md
Normal file
@ -0,0 +1,268 @@
|
||||
# chicken-master
|
||||
|
||||
A [re-frame](https://github.com/day8/re-frame) application designed to ... well, that part is up to
|
||||
you.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Project Overview
|
||||
|
||||
* Architecture:
|
||||
[Single Page Application (SPA)](https://en.wikipedia.org/wiki/Single-page_application)
|
||||
* Languages
|
||||
- Front end ([re-frame](https://github.com/day8/re-frame)): [ClojureScript](https://clojurescript.org/) (CLJS)
|
||||
- Back end/middleware ([Compojure](https://github.com/weavejester/compojure)): [Clojure](https://clojure.org/)
|
||||
- CSS compilation ([`lein-garden`](https://github.com/noprompt/lein-garden)): [Clojure](https://clojure.org/)
|
||||
* Dependencies
|
||||
- UI framework: [re-frame](https://github.com/day8/re-frame)
|
||||
([docs](https://github.com/day8/re-frame/blob/master/docs/README.md),
|
||||
[FAQs](https://github.com/day8/re-frame/blob/master/docs/FAQs/README.md)) ->
|
||||
[Reagent](https://github.com/reagent-project/reagent) ->
|
||||
[React](https://github.com/facebook/react)
|
||||
- Full stack framework: [Compojure](https://github.com/weavejester/compojure)
|
||||
([Wiki](https://github.com/weavejester/compojure/wiki), [API docs](http://weavejester.github.com/compojure)) ->
|
||||
[Ring](https://github.com/ring-clojure/ring)
|
||||
([Wiki](https://github.com/ring-clojure/ring/wiki), [API docs](http://ring-clojure.github.com/ring))
|
||||
- CSS rendering: [Garden](https://github.com/noprompt/garden)
|
||||
* Build tools
|
||||
- Project task & dependency management: [Leiningen](https://github.com/technomancy/leiningen)
|
||||
- CLJS compilation, REPL, & hot reload: [`shadow-cljs`](https://github.com/thheller/shadow-cljs)
|
||||
- CSS compilation: [`lein-garden`](https://github.com/noprompt/lein-garden)
|
||||
* Development tools
|
||||
- Debugging: [CLJS DevTools](https://github.com/binaryage/cljs-devtools)
|
||||
- Emacs integration: [CIDER](https://github.com/clojure-emacs/cider)
|
||||
|
||||
#### Directory structure
|
||||
|
||||
* [`/`](/../../): project config files
|
||||
* [`dev/`](dev/): source files compiled only with the [dev](#running-the-app) profile
|
||||
- [`cljs/user.cljs`](dev/cljs/user.cljs): symbols for use during development in the
|
||||
[ClojureScript REPL](#connecting-to-the-browser-repl-from-a-terminal)
|
||||
* [`resources/public/`](resources/public/): SPA root directory;
|
||||
[dev](#running-the-app) / [prod](#production) profile depends on the most recent build
|
||||
- [`index.html`](resources/public/index.html): SPA home page
|
||||
- Dynamic SPA content rendered in the following `div`:
|
||||
```html
|
||||
<div id="app"></div>
|
||||
```
|
||||
- Customizable; add headers, footers, links to other scripts and styles, etc.
|
||||
- Generated directories and files
|
||||
- Created on build with either the [dev](#running-the-app) or [prod](#production) profile
|
||||
- Deleted on `lein clean` (run by all `lein` aliases before building)
|
||||
- `css/`: compiled CSS (`lein-garden`, can also be
|
||||
[compiled manually](#compiling-css-with-lein-garden))
|
||||
- `js/compiled/`: compiled CLJS (`shadow-cljs`)
|
||||
- Not tracked in source control; see [`.gitignore`](.gitignore)
|
||||
* [`src/clj/chicken_master/`](src/clj/chicken_master/): Backend and middleware source files (Clojure,
|
||||
[Compojure](https://github.com/weavejester/compojure))
|
||||
* [`src/clj/chicken_master/`](src/clj/chicken_master/): CSS compilation source files (Clojure,
|
||||
[Garden](https://github.com/noprompt/garden))
|
||||
* [`src/cljs/chicken_master/`](src/cljs/chicken_master/): SPA source files (ClojureScript,
|
||||
[re-frame](https://github.com/Day8/re-frame))
|
||||
- [`core.cljs`](src/cljs/chicken_master/core.cljs): contains the SPA entry point, `init`
|
||||
|
||||
### Editor/IDE
|
||||
|
||||
Use your preferred editor or IDE that supports Clojure/ClojureScript development. See
|
||||
[Clojure tools](https://clojure.org/community/resources#_clojure_tools) for some popular options.
|
||||
|
||||
### Environment Setup
|
||||
|
||||
1. Install [JDK 8 or later](https://openjdk.java.net/install/) (Java Development Kit)
|
||||
2. Install [Leiningen](https://leiningen.org/#install) (Clojure/ClojureScript project task &
|
||||
dependency management)
|
||||
3. Install [Node.js](https://nodejs.org/) (JavaScript runtime environment) which should include
|
||||
[NPM](https://docs.npmjs.com/cli/npm) or if your Node.js installation does not include NPM also install it.
|
||||
7. Clone this repo and open a terminal in the `chicken-master` project root directory
|
||||
8. (Optional) Download project dependencies:
|
||||
```sh
|
||||
lein deps
|
||||
```
|
||||
|
||||
### Browser Setup
|
||||
|
||||
Browser caching should be disabled when developer tools are open to prevent interference with
|
||||
[`shadow-cljs`](https://github.com/thheller/shadow-cljs) hot reloading.
|
||||
|
||||
Custom formatters must be enabled in the browser before
|
||||
[CLJS DevTools](https://github.com/binaryage/cljs-devtools) can display ClojureScript data in the
|
||||
console in a more readable way.
|
||||
|
||||
#### Chrome/Chromium
|
||||
|
||||
1. Open [DevTools](https://developers.google.com/web/tools/chrome-devtools/) (Linux/Windows: `F12`
|
||||
or `Ctrl-Shift-I`; macOS: `⌘-Option-I`)
|
||||
2. Open DevTools Settings (Linux/Windows: `?` or `F1`; macOS: `?` or `Fn+F1`)
|
||||
3. Select `Preferences` in the navigation menu on the left, if it is not already selected
|
||||
4. Under the `Network` heading, enable the `Disable cache (while DevTools is open)` option
|
||||
5. Under the `Console` heading, enable the `Enable custom formatters` option
|
||||
|
||||
#### Firefox
|
||||
|
||||
1. Open [Developer Tools](https://developer.mozilla.org/en-US/docs/Tools) (Linux/Windows: `F12` or
|
||||
`Ctrl-Shift-I`; macOS: `⌘-Option-I`)
|
||||
2. Open [Developer Tools Settings](https://developer.mozilla.org/en-US/docs/Tools/Settings)
|
||||
(Linux/macOS/Windows: `F1`)
|
||||
3. Under the `Advanced settings` heading, enable the `Disable HTTP Cache (when toolbox is open)`
|
||||
option
|
||||
|
||||
Unfortunately, Firefox does not yet support custom formatters in their devtools. For updates, follow
|
||||
the enhancement request in their bug tracker:
|
||||
[1262914 - Add support for Custom Formatters in devtools](https://bugzilla.mozilla.org/show_bug.cgi?id=1262914).
|
||||
|
||||
## Development
|
||||
|
||||
### Running the App
|
||||
|
||||
Start a temporary local web server, build the app with the `dev` profile, and serve the app,
|
||||
browser test runner and karma test runner with hot reload:
|
||||
|
||||
```sh
|
||||
lein watch
|
||||
```
|
||||
|
||||
Please be patient; it may take over 20 seconds to see any output, and over 40 seconds to complete.
|
||||
|
||||
When `[:app] Build completed` appears in the output, browse to
|
||||
[http://localhost:8280/](http://localhost:8280/).
|
||||
|
||||
[`shadow-cljs`](https://github.com/thheller/shadow-cljs) will automatically push ClojureScript code
|
||||
changes to your browser on save. To prevent a few common issues, see
|
||||
[Hot Reload in ClojureScript: Things to avoid](https://code.thheller.com/blog/shadow-cljs/2019/08/25/hot-reload-in-clojurescript.html#things-to-avoid).
|
||||
|
||||
Opening the app in your browser starts a
|
||||
[ClojureScript browser REPL](https://clojurescript.org/reference/repl#using-the-browser-as-an-evaluation-environment),
|
||||
to which you may now connect.
|
||||
|
||||
#### Connecting to the browser REPL from Emacs with CIDER
|
||||
|
||||
Connect to the browser REPL:
|
||||
```
|
||||
M-x cider-jack-in-cljs
|
||||
```
|
||||
|
||||
See
|
||||
[Shadow CLJS User's Guide: Emacs/CIDER](https://shadow-cljs.github.io/docs/UsersGuide.html#cider)
|
||||
for more information. Note that the mentioned [`.dir-locals.el`](.dir-locals.el) file has already
|
||||
been created for you.
|
||||
|
||||
#### Connecting to the browser REPL from other editors
|
||||
|
||||
See
|
||||
[Shadow CLJS User's Guide: Editor Integration](https://shadow-cljs.github.io/docs/UsersGuide.html#_editor_integration).
|
||||
Note that `lein watch` runs `shadow-cljs watch` for you, and that this project's running build ids is
|
||||
`app`, `browser-test`, `karma-test`, or the keywords `:app`, `:browser-test`, `:karma-test` in a Clojure context.
|
||||
|
||||
Alternatively, search the web for info on connecting to a `shadow-cljs` ClojureScript browser REPL
|
||||
from your editor and configuration.
|
||||
|
||||
For example, in Vim / Neovim with `fireplace.vim`
|
||||
1. Open a `.cljs` file in the project to activate `fireplace.vim`
|
||||
2. In normal mode, execute the `Piggieback` command with this project's running build id, `:app`:
|
||||
```vim
|
||||
:Piggieback :app
|
||||
```
|
||||
|
||||
#### Connecting to the browser REPL from a terminal
|
||||
|
||||
1. Connect to the `shadow-cljs` nREPL:
|
||||
```sh
|
||||
lein repl :connect localhost:8777
|
||||
```
|
||||
The REPL prompt, `shadow.user=>`, indicates that is a Clojure REPL, not ClojureScript.
|
||||
|
||||
2. In the REPL, switch the session to this project's running build id, `:app`:
|
||||
```clj
|
||||
(shadow.cljs.devtools.api/nrepl-select :app)
|
||||
```
|
||||
The REPL prompt changes to `cljs.user=>`, indicating that this is now a ClojureScript REPL.
|
||||
3. See [`user.cljs`](dev/cljs/user.cljs) for symbols that are immediately accessible in the REPL
|
||||
without needing to `require`.
|
||||
|
||||
### Compiling CSS with `lein-garden`
|
||||
|
||||
Use Clojure and [Garden](https://github.com/noprompt/garden) to edit styles in `.clj` files located
|
||||
in the [`src/clj/chicken_master/`](src/clj/chicken_master/) directory. CSS files are compiled
|
||||
automatically on [`dev`](#running-the-app) or [`prod`](#production) build.
|
||||
|
||||
Manually compile CSS files:
|
||||
```sh
|
||||
lein garden once
|
||||
```
|
||||
|
||||
The `resources/public/css/` directory is created, containing the compiled CSS files.
|
||||
|
||||
#### Compiling CSS with Garden on change
|
||||
|
||||
Enable automatic compiling of CSS files when source `.clj` files are changed:
|
||||
```sh
|
||||
lein garden auto
|
||||
```
|
||||
|
||||
### Running `shadow-cljs` Actions
|
||||
|
||||
See a list of [`shadow-cljs CLI`](https://shadow-cljs.github.io/docs/UsersGuide.html#_command_line)
|
||||
actions:
|
||||
```sh
|
||||
lein run -m shadow.cljs.devtools.cli --help
|
||||
```
|
||||
|
||||
Please be patient; it may take over 10 seconds to see any output. Also note that some actions shown
|
||||
may not actually be supported, outputting "Unknown action." when run.
|
||||
|
||||
Run a shadow-cljs action on this project's build id (without the colon, just `app`):
|
||||
```sh
|
||||
lein run -m shadow.cljs.devtools.cli <action> app
|
||||
```
|
||||
### Debug Logging
|
||||
|
||||
The `debug?` variable in [`config.cljs`](src/cljs/chicken_master/config.cljs) defaults to `true` in
|
||||
[`dev`](#running-the-app) builds, and `false` in [`prod`](#production) builds.
|
||||
|
||||
Use `debug?` for logging or other tasks that should run only on `dev` builds:
|
||||
|
||||
```clj
|
||||
(ns chicken-master.example
|
||||
(:require [chicken-master.config :as config])
|
||||
|
||||
(when config/debug?
|
||||
(println "This message will appear in the browser console only on dev builds."))
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the app with the `prod` profile:
|
||||
|
||||
```sh
|
||||
lein with-profile release uberjar
|
||||
```
|
||||
|
||||
Please be patient; it may take a few seconds to see any output, and over 50 seconds to complete.
|
||||
|
||||
The `resources/public/js/compiled` directory is created, containing the compiled `app.js` and
|
||||
`manifest.edn` files. The `target/` directory is then created, containing the
|
||||
standalone `chicken-master.jar`.
|
||||
|
||||
### Running the Server
|
||||
|
||||
[Run the jar](https://github.com/ring-clojure/ring/wiki/Setup-for-production#run-the-server),
|
||||
setting the port the Ring server will use by setting the environment variable, `port`.
|
||||
|
||||
```sh
|
||||
port=2000 java -jar target/chicken-master.jar
|
||||
```
|
||||
|
||||
If `port` is not set, the server will run on port 3000 by default.
|
||||
|
||||
### Deploying to Heroku
|
||||
|
||||
1. [Create a Heroku app](https://devcenter.heroku.com/articles/creating-apps):
|
||||
```sh
|
||||
heroku create
|
||||
```
|
||||
|
||||
2. [Deploy the app code](https://devcenter.heroku.com/articles/git#deploying-code):
|
||||
|
||||
```sh
|
||||
git push heroku master
|
||||
```
|
93
project.clj
Normal file
93
project.clj
Normal file
@ -0,0 +1,93 @@
|
||||
(defproject chicken-master "0.1.0-SNAPSHOT"
|
||||
:dependencies [[org.clojure/clojure "1.10.1"]
|
||||
[org.clojure/clojurescript "1.10.773"
|
||||
:exclusions [com.google.javascript/closure-compiler-unshaded
|
||||
org.clojure/google-closure-library
|
||||
org.clojure/google-closure-library-third-party]]
|
||||
[thheller/shadow-cljs "2.11.0"]
|
||||
[reagent "0.10.0"]
|
||||
[re-frame "1.1.1"]
|
||||
[garden "1.3.10"]
|
||||
[ns-tracker "0.4.0"]
|
||||
[compojure "1.6.2"]
|
||||
[yogthos/config "1.1.7"]
|
||||
[ring "1.8.1"]]
|
||||
|
||||
:plugins [[lein-shadow "0.2.2"]
|
||||
[lein-garden "0.3.0"]
|
||||
[lein-shell "0.5.0"]]
|
||||
|
||||
:min-lein-version "2.9.0"
|
||||
|
||||
:jvm-opts ["-Xmx1G"]
|
||||
|
||||
:source-paths ["src/clj" "src/cljs"]
|
||||
|
||||
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"
|
||||
"resources/public/css"]
|
||||
|
||||
|
||||
:garden {:builds [{:id "screen"
|
||||
:source-paths ["src/clj"]
|
||||
:stylesheet chicken-master.css/screen
|
||||
:compiler {:output-to "resources/public/css/screen.css"
|
||||
:pretty-print? true}}]}
|
||||
|
||||
:shadow-cljs {:nrepl {:port 8777}
|
||||
|
||||
:builds {:app {:target :browser
|
||||
:output-dir "resources/public/js/compiled"
|
||||
:asset-path "/js/compiled"
|
||||
:modules {:app {:init-fn chicken-master.core/init
|
||||
:preloads [devtools.preload]}}
|
||||
|
||||
:devtools {:http-root "resources/public"
|
||||
:http-port 8280
|
||||
:http-handler chicken-master.handler/dev-handler
|
||||
}}}}
|
||||
|
||||
:shell {:commands {"karma" {:windows ["cmd" "/c" "karma"]
|
||||
:default-command "karma"}
|
||||
"open" {:windows ["cmd" "/c" "start"]
|
||||
:macosx "open"
|
||||
:linux "xdg-open"}}}
|
||||
|
||||
:aliases {"dev" ["do"
|
||||
["shell" "echo" "\"DEPRECATED: Please use lein watch instead.\""]
|
||||
["watch"]]
|
||||
"watch" ["with-profile" "dev" "do"
|
||||
["shadow" "watch" "app" "browser-test" "karma-test"]]
|
||||
|
||||
"prod" ["do"
|
||||
["shell" "echo" "\"DEPRECATED: Please use lein release instead.\""]
|
||||
["release"]]
|
||||
|
||||
"release" ["with-profile" "prod" "do"
|
||||
["shadow" "release" "app"]]
|
||||
|
||||
"build-report" ["with-profile" "prod" "do"
|
||||
["shadow" "run" "shadow.cljs.build-report" "app" "target/build-report.html"]
|
||||
["shell" "open" "target/build-report.html"]]
|
||||
|
||||
"karma" ["do"
|
||||
["shell" "echo" "\"DEPRECATED: Please use lein ci instead.\""]
|
||||
["ci"]]
|
||||
"ci" ["with-profile" "prod" "do"
|
||||
["shadow" "compile" "karma-test"]
|
||||
["shell" "karma" "start" "--single-run" "--reporters" "junit,dots"]]}
|
||||
|
||||
:profiles
|
||||
{:dev
|
||||
{:dependencies [[binaryage/devtools "1.0.2"]]
|
||||
:source-paths ["dev"]}
|
||||
|
||||
:prod {}
|
||||
|
||||
:uberjar {:source-paths ["env/prod/clj"]
|
||||
:omit-source true
|
||||
:main chicken-master.server
|
||||
:aot [chicken-master.server]
|
||||
:uberjar-name "chicken-master.jar"
|
||||
:prep-tasks ["compile" ["prod"]["garden" "once"]]}}
|
||||
|
||||
:prep-tasks [["garden" "once"]])
|
16
resources/public/index.html
Normal file
16
resources/public/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link href="css/screen.css" rel="stylesheet" type="text/css">
|
||||
<title>chicken-master</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
chicken-master is a JavaScript app. Please enable JavaScript to continue.
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<script src="js/compiled/app.js"></script>
|
||||
</body>
|
||||
</html>
|
60
src/clj/chicken_master/css.clj
Normal file
60
src/clj/chicken_master/css.clj
Normal file
@ -0,0 +1,60 @@
|
||||
(ns chicken-master.css
|
||||
(:require [garden.def :refer [defstyles]]))
|
||||
|
||||
(defstyles screen
|
||||
[:html {:height "100%"}
|
||||
[:body {:height "100%"}
|
||||
[:.full-height {:height "100%"}]
|
||||
[:.popup {:position :fixed
|
||||
:height "100%"
|
||||
:width "100%"
|
||||
:overflow :auto
|
||||
:z-index 1
|
||||
:background-color "rgba(0,0,0,0.4)"}
|
||||
[:form {
|
||||
:background-color "#fefefe"
|
||||
:margin "15% auto"
|
||||
:padding "20px"
|
||||
:border "1px solid #888"
|
||||
:width "15%"
|
||||
}
|
||||
[:.input-item
|
||||
[:label {:min-width "60px"
|
||||
:display :inline-block}]]
|
||||
[:.form-buttons {:margin "10px"}
|
||||
[:* {:margin "20px"}]]]]
|
||||
|
||||
[:.calendar {:display :grid
|
||||
:grid-template-columns "14% 14% 14% 14% 14% 14% 14%"
|
||||
:grid-template-rows "50% 50%"
|
||||
}
|
||||
[:.day-header {:border "2px solid black"
|
||||
:text-align :center
|
||||
:font-size "30px"}]
|
||||
[:.day.today {:border "2px solid red"}]
|
||||
[:.day {:border "2px solid black"
|
||||
:overflow :auto}
|
||||
|
||||
; If each day has a header, then hide the rest of the border
|
||||
[:.day-header {:border "none"
|
||||
:border-bottom "2px solid black"}]
|
||||
|
||||
[:.orders {:padding-left "25px"}
|
||||
|
||||
[:.actions {:display :none
|
||||
:float :right}]
|
||||
[:.order:hover [:.actions {:display :inline}]]
|
||||
|
||||
[:.who {:font-size "18px"
|
||||
:font-weight :bold
|
||||
:white-space :nowrap
|
||||
:overflow :hidden
|
||||
:text-overflow :ellipsis}]
|
||||
[:.products {:padding-left "25px"}
|
||||
[:.product {:margin-bottom "5px"}
|
||||
[:.product-amount {:width "40px"
|
||||
:margin-right "10px"
|
||||
:max-height "5px"}]]
|
||||
|
||||
]]]]]]
|
||||
)
|
15
src/clj/chicken_master/handler.clj
Normal file
15
src/clj/chicken_master/handler.clj
Normal file
@ -0,0 +1,15 @@
|
||||
(ns chicken-master.handler
|
||||
(:require
|
||||
[compojure.core :refer [GET defroutes]]
|
||||
[compojure.route :refer [resources]]
|
||||
[ring.util.response :refer [resource-response]]
|
||||
[ring.middleware.reload :refer [wrap-reload]]
|
||||
[shadow.http.push-state :as push-state]))
|
||||
|
||||
(defroutes routes
|
||||
(GET "/" [] (resource-response "index.html" {:root "public"}))
|
||||
(resources "/"))
|
||||
|
||||
(def dev-handler (-> #'routes wrap-reload push-state/handle))
|
||||
|
||||
(def handler routes)
|
9
src/clj/chicken_master/server.clj
Normal file
9
src/clj/chicken_master/server.clj
Normal file
@ -0,0 +1,9 @@
|
||||
(ns chicken-master.server
|
||||
(:require [chicken-master.handler :refer [handler]]
|
||||
[config.core :refer [env]]
|
||||
[ring.adapter.jetty :refer [run-jetty]])
|
||||
(:gen-class))
|
||||
|
||||
(defn -main [& _args]
|
||||
(let [port (or (env :port) 3000)]
|
||||
(run-jetty handler {:port port :join? false})))
|
81
src/cljs/chicken_master/calendar.cljs
Normal file
81
src/cljs/chicken_master/calendar.cljs
Normal file
@ -0,0 +1,81 @@
|
||||
(ns chicken-master.calendar
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.subs :as subs]
|
||||
[chicken-master.time :as time]
|
||||
))
|
||||
|
||||
(defn get-day [date]
|
||||
{:date date
|
||||
:customers [{:who "mr.blobby (649 234 234)" :when date :products {:eggs 2 :milk 3}}
|
||||
{:who "da police (0118 999 881 999 119 725 123123 12 3123 123 )" :when date :products {:eggs 12}}
|
||||
{:who "johnny" :when date :products {:eggs 5}}]})
|
||||
|
||||
|
||||
(defn modal [content on-submit]
|
||||
[:div {:class :popup}
|
||||
[:form {:action "#"}
|
||||
content
|
||||
[:div {:class :form-buttons}
|
||||
[:input {:type :submit :value "add"}]
|
||||
[:button {:type :button} "cancel"]]]])
|
||||
|
||||
(defn add-product [date order-id]
|
||||
(modal
|
||||
[:div
|
||||
[:div {:class :input-item}
|
||||
[:label {:for :product} "co"]
|
||||
[:input {:type :text :name :product :id :product}]]
|
||||
[:div {:class :input-item}
|
||||
[:label {:for :amount} "ile"]
|
||||
[:input {:type :number :name :amount :id :amount}]]]
|
||||
js/console.log))
|
||||
|
||||
(defn add-order [date]
|
||||
(modal
|
||||
[:div
|
||||
[:div {:class :input-item}
|
||||
[:label {:for :who} "kto"]
|
||||
[:input {:type :text :name :who :id :who :required true :step "60"}]]
|
||||
[:div {:class :input-item}
|
||||
[:label {:for :when} "kiedy"]
|
||||
[:input {:type :time :name :when :id :when}]]
|
||||
[:div {}
|
||||
[:label "co"]
|
||||
]]
|
||||
js/console.log))
|
||||
|
||||
(defn format-product [[product amount]]
|
||||
[:li {:class :product}
|
||||
[:input {:class :product-amount :type :number :min 0 :defaultValue amount}]
|
||||
[:span {:class :product-name} product]])
|
||||
|
||||
(defn format-order [{:keys [who when products]}]
|
||||
[:li {:class :order}
|
||||
[:div {:class :actions}
|
||||
[:button "+"] [:button "O"] [:button "-"]]
|
||||
[:div {:class :who} who]
|
||||
(if (subs/settings :show-order-time)
|
||||
[:div {:class :when} (str (.getHours when) ":" (.getMinutes when))])
|
||||
(->> products
|
||||
(map format-product)
|
||||
(into [:ul {:class :products}]))])
|
||||
|
||||
(defn day [{:keys [date customers]}]
|
||||
[:div {:class [:day (when (time/today? date) :today)]}
|
||||
[:div {:class :day-header} (time/format-date date)]
|
||||
[:div
|
||||
[:ul {:class :orders}
|
||||
(map format-order customers)
|
||||
[:button {:type :button} "+"]]]])
|
||||
|
||||
(defn calendar-header []
|
||||
(->> (subs/settings :day-names)
|
||||
(map (fn [day] [:div {:class :day-header} day]))
|
||||
(into [])))
|
||||
|
||||
(defn calendar [days]
|
||||
(->> days
|
||||
(map (comp day get-day))
|
||||
(concat (when-not (subs/settings :always-day-names) (calendar-header)))
|
||||
(into [:div {:class [:calendar :full-height]}])))
|
4
src/cljs/chicken_master/config.cljs
Normal file
4
src/cljs/chicken_master/config.cljs
Normal file
@ -0,0 +1,4 @@
|
||||
(ns chicken-master.config)
|
||||
|
||||
(def debug?
|
||||
^boolean goog.DEBUG)
|
24
src/cljs/chicken_master/core.cljs
Normal file
24
src/cljs/chicken_master/core.cljs
Normal file
@ -0,0 +1,24 @@
|
||||
(ns chicken-master.core
|
||||
(:require
|
||||
[reagent.dom :as rdom]
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.events :as events]
|
||||
[chicken-master.views :as views]
|
||||
[chicken-master.config :as config]
|
||||
))
|
||||
|
||||
|
||||
(defn dev-setup []
|
||||
(when config/debug?
|
||||
(println "dev mode")))
|
||||
|
||||
(defn ^:dev/after-load mount-root []
|
||||
(re-frame/clear-subscription-cache!)
|
||||
(let [root-el (.getElementById js/document "app")]
|
||||
(rdom/unmount-component-at-node root-el)
|
||||
(rdom/render [views/main-panel] root-el)))
|
||||
|
||||
(defn init []
|
||||
(re-frame/dispatch-sync [::events/initialize-db])
|
||||
(dev-setup)
|
||||
(mount-root))
|
4
src/cljs/chicken_master/db.cljs
Normal file
4
src/cljs/chicken_master/db.cljs
Normal file
@ -0,0 +1,4 @@
|
||||
(ns chicken-master.db)
|
||||
|
||||
(def default-db
|
||||
{:name "re-frame"})
|
10
src/cljs/chicken_master/events.cljs
Normal file
10
src/cljs/chicken_master/events.cljs
Normal file
@ -0,0 +1,10 @@
|
||||
(ns chicken-master.events
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.db :as db]
|
||||
))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::initialize-db
|
||||
(fn [_ _]
|
||||
db/default-db))
|
13
src/cljs/chicken_master/subs.cljs
Normal file
13
src/cljs/chicken_master/subs.cljs
Normal file
@ -0,0 +1,13 @@
|
||||
(ns chicken-master.subs
|
||||
(:require
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::name
|
||||
(fn [db]
|
||||
(:name db)))
|
||||
|
||||
(def settings {:first-day-offset 1
|
||||
:day-names ["Niedz" "Pon" "Wt" "Śr" "Czw" "Pt" "Sob"]
|
||||
:always-day-names true
|
||||
:show-order-time false})
|
35
src/cljs/chicken_master/time.cljs
Normal file
35
src/cljs/chicken_master/time.cljs
Normal file
@ -0,0 +1,35 @@
|
||||
(ns chicken-master.time
|
||||
(:require
|
||||
[chicken-master.subs :as subs])
|
||||
(:import [goog.date DateTime Date Interval]))
|
||||
|
||||
(defn date-offset
|
||||
"Return the `date` offset by the given number of `days`"
|
||||
[date days]
|
||||
(let [new-day (new DateTime date)]
|
||||
(.add new-day (new Interval Interval/DAYS days))
|
||||
new-day))
|
||||
|
||||
(defn start-of-week
|
||||
"Get the start of the week for the given `date"
|
||||
[date]
|
||||
(->> (.getDay date)
|
||||
(- (subs/settings :first-day-offset))
|
||||
(date-offset date)))
|
||||
|
||||
(defn days-range
|
||||
"Return dates starting from `date`"
|
||||
([date] (map (partial date-offset date) (range)))
|
||||
([date n] (take n (days-range date))))
|
||||
|
||||
(defn same-day?
|
||||
"Returns true when both dates are from the same day" [d1 d2]
|
||||
(-> (new Date d1)
|
||||
(.equals (new Date d2))))
|
||||
|
||||
(defn today? "true when `d1` is today" [d1] (same-day? (js/Date.) d1))
|
||||
|
||||
(defn format-date [date]
|
||||
(str
|
||||
(->> date .getDay (nth (subs/settings :day-names)))
|
||||
" " (.getMonth date) "/" (.getDate date)))
|
17
src/cljs/chicken_master/views.cljs
Normal file
17
src/cljs/chicken_master/views.cljs
Normal file
@ -0,0 +1,17 @@
|
||||
(ns chicken-master.views
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[chicken-master.subs :as subs]
|
||||
[chicken-master.calendar :as cal]
|
||||
[chicken-master.time :as time]
|
||||
))
|
||||
|
||||
(defn main-panel []
|
||||
(let [name (re-frame/subscribe [::subs/name])]
|
||||
[:div {:class :full-height}
|
||||
(cal/add-order (new js/Date))
|
||||
(-> (new js/Date)
|
||||
time/start-of-week
|
||||
(time/days-range 14)
|
||||
cal/calendar)
|
||||
]))
|
1
src/cljs/deps.cljs
Normal file
1
src/cljs/deps.cljs
Normal file
@ -0,0 +1 @@
|
||||
{:npm-dev-deps {"shadow-cljs" "2.11.0"}}
|
Loading…
x
Reference in New Issue
Block a user