Compare commits
23 commits
Author | SHA1 | Date | |
---|---|---|---|
52f76dad12 | |||
f18c384e79 | |||
|
e76b69d0ff | ||
|
9e1807830d | ||
|
645342ba52 | ||
|
c29a3d26a1 | ||
|
8c50ac5550 | ||
|
9af648f305 | ||
|
51af80d6ba | ||
|
d960a1413c | ||
|
baa3a02a15 | ||
|
8a4e366516 | ||
|
fbb1ec3c7d | ||
|
5d71f20fba | ||
|
716ad05626 | ||
|
fbe17e5c80 | ||
|
59c3e8475c | ||
|
59e852f516 | ||
|
97befd868c | ||
|
140d01a460 | ||
|
6871bfd3bf | ||
|
f798a27a90 | ||
|
3cc0857973 |
12 changed files with 704 additions and 356 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -1,4 +1,13 @@
|
||||||
.idea/
|
.idea/
|
||||||
__pycache__/
|
|
||||||
env/
|
|
||||||
*.db
|
*.db
|
||||||
|
|
||||||
|
# vlang
|
||||||
|
main
|
||||||
|
v
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
vls.log
|
||||||
|
.env
|
2
Makefile
2
Makefile
|
@ -1,2 +0,0 @@
|
||||||
all:
|
|
||||||
FLASK_ENV=development FLASK_APP=main.py flask run
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
De pannenkoekenwachtrij voor wanneer er pannenkoeken worden gebakken in de kelder.
|
De pannenkoekenwachtrij voor wanneer er pannenkoeken worden gebakken in de kelder.
|
||||||
|
|
||||||
Server opzetten doe je door `FLASK_APP=main.py flask run` te runnen.
|
Server opzetten doe je door `v run .` te runnen.
|
57
main.py
57
main.py
|
@ -1,57 +0,0 @@
|
||||||
from flask import Flask, render_template, request, redirect, url_for, jsonify
|
|
||||||
import sqlite3
|
|
||||||
|
|
||||||
# create table orders (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, remark TEXT, created_at datetime default current_timestamp, status text default "besteld");
|
|
||||||
|
|
||||||
# c = conn.cursor()
|
|
||||||
# Create table
|
|
||||||
# c.execute('''CREATE TABLE order
|
|
||||||
# (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, remark TEXT)''')
|
|
||||||
# conn.commit()
|
|
||||||
# conn.close()
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def execute_query(query):
|
|
||||||
conn = sqlite3.connect('user.db')
|
|
||||||
c = conn.cursor()
|
|
||||||
|
|
||||||
print(f"{query=}")
|
|
||||||
results = []
|
|
||||||
|
|
||||||
# Insert a row of data
|
|
||||||
try:
|
|
||||||
c.execute(query)
|
|
||||||
results = c.fetchall()
|
|
||||||
except:
|
|
||||||
print("An sql execute error occured")
|
|
||||||
|
|
||||||
# Save (commit) the changes
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
# We can also close the connection if we are done with it.
|
|
||||||
# Just be sure any changes have been committed or they will be lost.
|
|
||||||
conn.close()
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pancake_statuses = ["besteld", "aan_het_bakken", "klaar"]
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
|
||||||
def home():
|
|
||||||
return render_template("home.html")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/execute", methods=["POST"])
|
|
||||||
def execute():
|
|
||||||
content = request.json
|
|
||||||
print("Query : ", content)
|
|
||||||
response = execute_query(content["lecode"])
|
|
||||||
return jsonify(response)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run()
|
|
192
poetry.lock
generated
192
poetry.lock
generated
|
@ -1,192 +0,0 @@
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Backport of Python 3 csv module"
|
|
||||||
name = "backports.csv"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.0.7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Helpers for building command-line apps"
|
|
||||||
name = "cli-helpers"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.2.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Pygments = ">=1.6"
|
|
||||||
"backports.csv" = ">=1.0.0"
|
|
||||||
configobj = ">=5.0.5"
|
|
||||||
tabulate = ">=0.8.2"
|
|
||||||
terminaltables = ">=3.0.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Composable command line interface toolkit"
|
|
||||||
name = "click"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "7.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Config file reading, writing and validation."
|
|
||||||
name = "configobj"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "5.0.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A simple framework for building complex web applications."
|
|
||||||
name = "flask"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|
||||||
version = "1.1.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Jinja2 = ">=2.10.1"
|
|
||||||
Werkzeug = ">=0.15"
|
|
||||||
click = ">=5.1"
|
|
||||||
itsdangerous = ">=0.24"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Various helpers to pass data to untrusted environments and back."
|
|
||||||
name = "itsdangerous"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A very fast and expressive template engine."
|
|
||||||
name = "jinja2"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "2.10.3"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
MarkupSafe = ">=0.23"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "CLI for SQLite Databases with auto-completion and syntax highlighting."
|
|
||||||
name = "litecli"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Pygments = ">=1.6"
|
|
||||||
cli-helpers = ">=1.0.1"
|
|
||||||
click = ">=4.1"
|
|
||||||
configobj = ">=5.0.5"
|
|
||||||
prompt-toolkit = ">=2.0.0,<2.1.0"
|
|
||||||
sqlparse = ">=0.2.2,<0.3.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Safely add untrusted strings to HTML/XML markup."
|
|
||||||
name = "markupsafe"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
|
||||||
version = "1.1.1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Library for building powerful interactive command lines in Python"
|
|
||||||
name = "prompt-toolkit"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
|
||||||
version = "2.0.10"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = ">=1.9.0"
|
|
||||||
wcwidth = "*"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Pygments is a syntax highlighting package written in Python."
|
|
||||||
name = "pygments"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|
||||||
version = "2.5.2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
|
||||||
name = "six"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
|
||||||
version = "1.13.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Non-validating SQL parser"
|
|
||||||
name = "sqlparse"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.2.4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Pretty-print tabular data"
|
|
||||||
name = "tabulate"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.8.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
wcwidth = "*"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Generate simple tables in terminals from a nested list of strings."
|
|
||||||
name = "terminaltables"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Measures number of Terminal column cells of wide-character codes"
|
|
||||||
name = "wcwidth"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.1.7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "The comprehensive WSGI web application library."
|
|
||||||
name = "werkzeug"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "0.16.0"
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
content-hash = "cedb57d5530f510b56b00c8d54c8beec6fe6f2d9573d1f89eb4c3234c3361a69"
|
|
||||||
python-versions = "^3.8"
|
|
||||||
|
|
||||||
[metadata.hashes]
|
|
||||||
"backports.csv" = ["1277dfff73130b2e106bf3dd347adb3c5f6c4340882289d88f31240da92cbd6d", "21f6e09bab589e6c1f877edbc40277b65e626262a86e69a70137db714eaac5ce"]
|
|
||||||
cli-helpers = ["0885ab0a6e0b03f39bcbd6ebd1c439131a94a20d8f5ba2b3e464e9fa05a1a80b", "98db22eaa86827d99ee6af9f5f3923142d04df256425204530842b032849a165", "e8be0d0f079798490e6bc2a46087a045a8e5b64964eceb210bbb7ba1d98baacd"]
|
|
||||||
click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"]
|
|
||||||
configobj = ["a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902"]
|
|
||||||
flask = ["13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", "45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6"]
|
|
||||||
itsdangerous = ["321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"]
|
|
||||||
jinja2 = ["74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", "9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"]
|
|
||||||
litecli = ["94f531aa9da58af559f1944ff09f2f2692dc1ce9ed3b0c8f2acf6107b4e605f6", "a42950fc0e4387b29fbeef28a048d9fb4059327e1e32e90ea8015ee6db8ffea4"]
|
|
||||||
markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"]
|
|
||||||
prompt-toolkit = ["46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4", "e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31", "f15af68f66e664eaa559d4ac8a928111eebd5feda0c11738b5998045224829db"]
|
|
||||||
pygments = ["2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b", "98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"]
|
|
||||||
six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"]
|
|
||||||
sqlparse = ["ce028444cfab83be538752a2ffdb56bc417b7784ff35bb9a3062413717807dec", "d9cf190f51cbb26da0412247dfe4fb5f4098edb73db84e02f9fc21fdca31fed4"]
|
|
||||||
tabulate = ["5470cc6687a091c7042cee89b2946d9235fe9f6d49c193a4ae2ac7bf386737c8"]
|
|
||||||
terminaltables = ["f3eb0eb92e3833972ac36796293ca0906e998dc3be91fbe1f8615b331b853b81"]
|
|
||||||
wcwidth = ["3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", "f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"]
|
|
||||||
werkzeug = ["7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", "e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"]
|
|
|
@ -1,16 +0,0 @@
|
||||||
[tool.poetry]
|
|
||||||
name = "pannenkoekenwachtrij"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
authors = ["Maxime Bloch <me@mcbloch.dev>"]
|
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
|
||||||
python = "^3.8"
|
|
||||||
flask = "^1.1"
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
|
||||||
litecli = "^1.2"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry>=0.12"]
|
|
||||||
build-backend = "poetry.masonry.api"
|
|
339
src/main.v
Normal file
339
src/main.v
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import vweb
|
||||||
|
import db.sqlite
|
||||||
|
import time
|
||||||
|
import net.http
|
||||||
|
import arrays
|
||||||
|
import maps
|
||||||
|
import math.stats
|
||||||
|
|
||||||
|
const http_port = 8080
|
||||||
|
|
||||||
|
enum Status {
|
||||||
|
besteld = 0
|
||||||
|
bakken = 1
|
||||||
|
klaar = 2
|
||||||
|
afgegeven = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (s Status) str() string {
|
||||||
|
return match s {
|
||||||
|
.besteld { 'Pannenkoek besteld' }
|
||||||
|
.bakken { 'Pannenkoek aan het bakken' }
|
||||||
|
.klaar { 'Pannenkoek klaar' }
|
||||||
|
.afgegeven { 'Pannenkoek afgegeven' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
id int @[primary; sql: serial]
|
||||||
|
status int
|
||||||
|
name string
|
||||||
|
remark string
|
||||||
|
order_time time.Time
|
||||||
|
delivery_time time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (p Person) str() string {
|
||||||
|
return 'Person[id:${p.id}, name: ${p.name}, status:${p.status}, time:${p.order_time}, end:${p.delivery_time}]'
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (p Person) order_time_humanized() string {
|
||||||
|
return p.order_time.relative()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (p Person) remark() string {
|
||||||
|
return if p.remark.len > 0 {
|
||||||
|
'(${p.remark})'
|
||||||
|
} else {
|
||||||
|
''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (p Person) status_str() string {
|
||||||
|
unsafe {
|
||||||
|
s := Status(p.status)
|
||||||
|
return s.str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Database ===
|
||||||
|
|
||||||
|
pub fn create_db_connection() !sqlite.DB {
|
||||||
|
return sqlite.connect('pancakes.db')!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_people() ![]Person {
|
||||||
|
status_filter := int(Status.afgegeven)
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where status < status_filter
|
||||||
|
}!
|
||||||
|
return people
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_finished_count() !int {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where status == 3
|
||||||
|
}!
|
||||||
|
return people.len
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PerHour {
|
||||||
|
t time.Time
|
||||||
|
label string
|
||||||
|
amount int
|
||||||
|
percentage int
|
||||||
|
color string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_all() ![]Person {
|
||||||
|
return sql app.db {
|
||||||
|
select from Person order by id desc
|
||||||
|
}!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_last_delivered() ![]Person {
|
||||||
|
return sql app.db {
|
||||||
|
select from Person order by delivery_time desc limit 1
|
||||||
|
}!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_ordered_per_hour() ![]PerHour {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person
|
||||||
|
}!
|
||||||
|
|
||||||
|
grouped := arrays.group_by(people, fn (p Person) string {
|
||||||
|
return '${p.order_time.hour}:${int(p.order_time.minute / 30) * 30}'
|
||||||
|
})
|
||||||
|
|
||||||
|
max_per_hour := arrays.max(grouped.values().map(it.len)) or { 1 } + 10
|
||||||
|
|
||||||
|
mut grouped_arr := maps.to_array(grouped, fn [max_per_hour] (k string, v []Person) PerHour {
|
||||||
|
return PerHour{
|
||||||
|
t: v[0].order_time
|
||||||
|
label: k
|
||||||
|
amount: v.len
|
||||||
|
percentage: int(v.len * 100 / max_per_hour)
|
||||||
|
color: (if v[0].order_time.hour % 2 == 0 { 'green' } else { 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
grouped_arr.sort(a.t < b.t)
|
||||||
|
return grouped_arr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_finished_per_hour() ![]PerHour {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where status == 3
|
||||||
|
}!
|
||||||
|
|
||||||
|
grouped := arrays.group_by(people, fn (p Person) string {
|
||||||
|
return '${p.order_time.hour}:${int(p.order_time.minute / 30) * 30}'
|
||||||
|
})
|
||||||
|
|
||||||
|
max_per_hour := arrays.max(grouped.values().map(it.len)) or { 1 } + 10
|
||||||
|
|
||||||
|
mut grouped_arr := maps.to_array(grouped, fn [max_per_hour] (k string, v []Person) PerHour {
|
||||||
|
return PerHour{
|
||||||
|
t: v[0].order_time
|
||||||
|
label: k
|
||||||
|
amount: v.len
|
||||||
|
percentage: int(v.len * 100 / max_per_hour)
|
||||||
|
color: (if v[0].order_time.hour % 2 == 0 { 'green' } else { 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
grouped_arr.sort(a.t < b.t)
|
||||||
|
return grouped_arr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_ppu() !f64 {
|
||||||
|
mut people := sql app.db {
|
||||||
|
select from Person where status == 3
|
||||||
|
}!
|
||||||
|
if people.len == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
people.sort(a.order_time < b.order_time)
|
||||||
|
time_range := people.last().order_time - people.first().order_time
|
||||||
|
return people.len / time_range.hours()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_mean_time_between_pannenkoeken() !time.Duration {
|
||||||
|
time_zero := time.Time{
|
||||||
|
unix: 0
|
||||||
|
}
|
||||||
|
mut people := sql app.db {
|
||||||
|
select from Person where (status == 3 && delivery_time > time_zero) order by delivery_time desc limit 10
|
||||||
|
}!
|
||||||
|
return stats.mean(arrays.window(people, size: 2).map(it[0].delivery_time - it[1].delivery_time))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_last_done_person() ![]Person {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where status == 3 order by delivery_time desc limit 1
|
||||||
|
}!
|
||||||
|
return people
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) get_next_person() ![]Person {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where status < 3 order by id limit 1
|
||||||
|
}!
|
||||||
|
return people
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) do_status_update(user_id int) !Person {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where id == user_id
|
||||||
|
}!
|
||||||
|
person := people.first()
|
||||||
|
sql app.db {
|
||||||
|
update Person set status = person.status + 1 where id == person.id
|
||||||
|
}!
|
||||||
|
if person.status == 2 {
|
||||||
|
sql app.db {
|
||||||
|
update Person set delivery_time = time.now() where id == person.id
|
||||||
|
}!
|
||||||
|
}
|
||||||
|
return person
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut app App) do_add_person(name string, remark string) ! {
|
||||||
|
people := sql app.db {
|
||||||
|
select from Person where name == name && status < 3
|
||||||
|
}!
|
||||||
|
|
||||||
|
if people.len == 0 {
|
||||||
|
p := Person{
|
||||||
|
status: 0
|
||||||
|
order_time: time.now()
|
||||||
|
name: name
|
||||||
|
remark: remark
|
||||||
|
}
|
||||||
|
sql app.db {
|
||||||
|
insert p into Person
|
||||||
|
}!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === WEB ===
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
vweb.Context
|
||||||
|
mut:
|
||||||
|
db sqlite.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut app App) before_request() {
|
||||||
|
println('[Vweb] ${app.Context.req.method} ${app.Context.req.url}')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println('Start 🥞 webserver')
|
||||||
|
mut db := create_db_connection() or { panic(err) }
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
create table Person
|
||||||
|
} or { panic('error on create table: ${err}') }
|
||||||
|
|
||||||
|
// db.close() or { panic(err) }
|
||||||
|
|
||||||
|
vweb.run(&App{
|
||||||
|
db: db
|
||||||
|
}, http_port)
|
||||||
|
}
|
||||||
|
|
||||||
|
@['/'; get]
|
||||||
|
pub fn (mut app App) home() vweb.Result {
|
||||||
|
people := app.get_people() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
person_finished_count := app.get_finished_count() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
finished_per_hour := app.get_finished_per_hour() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
ordered_per_hour := app.get_ordered_per_hour() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
// pannenkoek per uur
|
||||||
|
ppu := app.get_ppu() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
all_people := app.get_all() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
mean_time := app.get_mean_time_between_pannenkoeken() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
mut last_delivered := app.get_last_delivered() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
if last_delivered.len == 0 {
|
||||||
|
last_delivered << Person{
|
||||||
|
delivery_time: time.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Time to pannenkoek
|
||||||
|
time_since_last := (time.now() - last_delivered.first().delivery_time)
|
||||||
|
ttp := time.unix(i64(mean_time.seconds() - time_since_last.seconds())) - time.unix(0)
|
||||||
|
|
||||||
|
return $vweb.html()
|
||||||
|
}
|
||||||
|
|
||||||
|
@['/banner'; get]
|
||||||
|
pub fn (mut app App) banner() vweb.Result {
|
||||||
|
last_done := app.get_last_done_person() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
next_person := app.get_next_person() or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
now := time.now()
|
||||||
|
|
||||||
|
return $vweb.html()
|
||||||
|
}
|
||||||
|
|
||||||
|
@['/status_update'; post]
|
||||||
|
pub fn (mut app App) status_update() vweb.Result {
|
||||||
|
if person := app.do_status_update(app.form['id'].int()) {
|
||||||
|
if person.status == 1 {
|
||||||
|
spawn fn () {
|
||||||
|
http.post('http://10.1.0.224:8080/blink', '') or {}
|
||||||
|
}()
|
||||||
|
spawn fn (name string) {
|
||||||
|
http.post('http://10.1.2.3', 'ScrollingText >>> ${name} <<< Enjoy! ') or {}
|
||||||
|
http.post('http://10.1.2.3', 'Option text_trailingWhitespace 1') or {}
|
||||||
|
}(person.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.redirect('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
@['/add_person'; post]
|
||||||
|
pub fn (mut app App) add_person() vweb.Result {
|
||||||
|
name := app.form['name']
|
||||||
|
if name.len == 0 {
|
||||||
|
return app.redirect('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
app.do_add_person(app.form['name'], app.form['remark']) or {
|
||||||
|
app.set_status(400, '')
|
||||||
|
return app.text('${err}')
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.redirect('/')
|
||||||
|
}
|
74
src/templates/banner.html
Normal file
74
src/templates/banner.html
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.5">
|
||||||
|
<title>🥞wachtrij</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/tuicss@@2.1.1/dist/tuicss.min.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
.tui-window {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tui-table tbody tr td {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
setInterval(function(){
|
||||||
|
location.reload()
|
||||||
|
}, 1000)
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="tui-bg-green-black">
|
||||||
|
<div style="margin: auto; width: 60%; margin-top: 40px;">
|
||||||
|
<div class="container" style="width: 100%">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<h1>Previous pancake</h1>
|
||||||
|
@if last_done.len > 0
|
||||||
|
@{now - last_done[0].delivery_time}
|
||||||
|
@else
|
||||||
|
No pancakes done yet
|
||||||
|
@end
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<h1>NEXT UP</h1>
|
||||||
|
@if next_person.len > 0
|
||||||
|
@{next_person[0].name}
|
||||||
|
@else
|
||||||
|
Nobody in the queue
|
||||||
|
@end
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
270
src/templates/home.html
Normal file
270
src/templates/home.html
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.5">
|
||||||
|
<title>🥞wachtrij</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/tuicss@@2.1.1/dist/tuicss.min.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
.tui-window {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tui-table tbody tr td {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="tui-bg-green-black">
|
||||||
|
<div style="margin: auto; width: 60%; margin-top: 40px;">
|
||||||
|
<div class="container" style="width: 100%">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m6">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
Welkom bij de 🥞wachtrij
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col m6">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
Er zijn al @person_finished_count 🥞 afgeleverd!
|
||||||
|
<br />
|
||||||
|
Dat is @{ppu:.2} 🥞/uur
|
||||||
|
<br />
|
||||||
|
Gemiddelde tijd tussen 🥞: @{mean_time.str()}
|
||||||
|
<br/>
|
||||||
|
<span id="ttp">
|
||||||
|
TTP:
|
||||||
|
@if ttp < 0
|
||||||
|
Soon™
|
||||||
|
@else
|
||||||
|
@ttp
|
||||||
|
@end
|
||||||
|
</span>
|
||||||
|
<script>
|
||||||
|
function time_left_string(time_left) {
|
||||||
|
let minutes = Math.floor(time_left / 60000);
|
||||||
|
let seconds = Math.floor((time_left - minutes * 60000) / 1000);
|
||||||
|
if (seconds < 10) {
|
||||||
|
seconds = "0" + seconds;
|
||||||
|
}
|
||||||
|
return minutes + ":" + seconds + ".000";
|
||||||
|
}
|
||||||
|
|
||||||
|
let ttp = new Date(@ttp.milliseconds())
|
||||||
|
console.log(ttp)
|
||||||
|
if (ttp.getTime() > 0){
|
||||||
|
const ttp_span = document.getElementById('ttp')
|
||||||
|
console.log('sd')
|
||||||
|
setInterval(function(){
|
||||||
|
console.log(ttp.getTime())
|
||||||
|
ttp.setTime(ttp.getTime() - 1000)
|
||||||
|
console.log(ttp.getTime())
|
||||||
|
console.log('----')
|
||||||
|
if (ttp.getTime() <= 0) {
|
||||||
|
ttp_span.innerText = "TTP: Soon™"
|
||||||
|
} else {
|
||||||
|
ttp_span.innerText = "TTP: " + time_left_string(ttp)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<form action="/add_person" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12" style="display: inline-flex">
|
||||||
|
Naam van de volgende:
|
||||||
|
<input class="tui-input" type="text" id="name" name="name"
|
||||||
|
style="margin-left: 10px; flex: 1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12" style="display: inline-flex">
|
||||||
|
Specifieke opmerkingen:
|
||||||
|
<input class="tui-input" type="text" id="remark" name="remark"
|
||||||
|
style="margin-left: 10px; flex: 1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 10px">
|
||||||
|
<div class="col m12" style="display: inline-flex">
|
||||||
|
<input class="tui-button green-168" type="submit" value="Persoon toevoegen"
|
||||||
|
style="flex: 1; margin-bottom: 0px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if people.len > 0
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<form action="/status_update" method="POST">
|
||||||
|
<input type="hidden" name="id" value="@{people[0].id}">
|
||||||
|
<input class="tui-button green-168" type="submit" value="Update First Person"
|
||||||
|
style="width: 100%">
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@end
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<h2>Zie hieronder de lijst van personen die een 🥞 willen</h2>
|
||||||
|
<table class="tui-table" style="width: 100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"
|
||||||
|
style="text-align:center; vertical-align:middle; padding-top: 20px">Volgende
|
||||||
|
persoon</td>
|
||||||
|
</tr>
|
||||||
|
@if people.len > 0
|
||||||
|
@for person in people[..1]
|
||||||
|
<tr>
|
||||||
|
<td>@person.name @person.remark()</td>
|
||||||
|
<td>@person.status_str()</td>
|
||||||
|
<td>@person.order_time_humanized()</td>
|
||||||
|
<td>
|
||||||
|
<form action="/status_update" method="POST">
|
||||||
|
<input type="hidden" name="id" value="@person.id">
|
||||||
|
<input class="tui-button green-168" type="submit" value="Update">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@end
|
||||||
|
@end
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" style='text-align:center; vertical-align:middle'>Andere personen
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@if people.len > 1
|
||||||
|
@for person in people[1..]
|
||||||
|
<tr>
|
||||||
|
<td>@person.name @person.remark()</td>
|
||||||
|
<td>@person.status_str()</td>
|
||||||
|
<td>@person.order_time_humanized()</td>
|
||||||
|
<td>
|
||||||
|
<form action="/status_update" method="POST">
|
||||||
|
<input type="hidden" name="id" value="@person.id">
|
||||||
|
<input class="tui-button green-168" type="submit" value="Update">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@end
|
||||||
|
@end
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m12">
|
||||||
|
<div class="tui-window red-168">
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<h2>Aantal gebakken 🥞</h2>
|
||||||
|
<div class="tui-chart-vertical" style="width: 100%; height: 200px;">
|
||||||
|
<div class="tui-chart-display">
|
||||||
|
@for ph in finished_per_hour
|
||||||
|
<div class="tui-chart-value @ph.color-168" style="height: @{ph.percentage}%;">
|
||||||
|
@ph.amount</div>
|
||||||
|
@end
|
||||||
|
</div>
|
||||||
|
<!-- <div class="tui-chart-y-axis">
|
||||||
|
<div class="tui-chart-legend">100%</div>
|
||||||
|
<div class="tui-chart-legend">75%</div>
|
||||||
|
<div class="tui-chart-legend">50%</div>
|
||||||
|
<div class="tui-chart-legend">25%</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="tui-chart-x-axis">
|
||||||
|
@for ph in finished_per_hour
|
||||||
|
<div class="tui-chart-legend">@ph.label</div>
|
||||||
|
@end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="tui-fieldset">
|
||||||
|
<h2>Aantal bestelde 🥞</h2>
|
||||||
|
<div class="tui-chart-vertical" style="width: 100%; height: 200px;">
|
||||||
|
<div class="tui-chart-display">
|
||||||
|
@for ph in ordered_per_hour
|
||||||
|
<div class="tui-chart-value @ph.color-168" style="height: @{ph.percentage}%;">
|
||||||
|
@ph.amount</div>
|
||||||
|
@end
|
||||||
|
</div>
|
||||||
|
<!-- <div class="tui-chart-y-axis">
|
||||||
|
<div class="tui-chart-legend">100%</div>
|
||||||
|
<div class="tui-chart-legend">75%</div>
|
||||||
|
<div class="tui-chart-legend">50%</div>
|
||||||
|
<div class="tui-chart-legend">25%</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="tui-chart-x-axis">
|
||||||
|
@for ph in ordered_per_hour
|
||||||
|
<div class="tui-chart-legend">@ph.label</div>
|
||||||
|
@end
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <table class="container tui-window">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>id</th>
|
||||||
|
<th>name</th>
|
||||||
|
<th>remark</th>
|
||||||
|
<th>status</th>
|
||||||
|
<th>order time</th>
|
||||||
|
<th>delivery time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@for p in all_people
|
||||||
|
<tr>
|
||||||
|
<td>@p.id</td>
|
||||||
|
<td>@p.name</td>
|
||||||
|
<td>@p.remark</td>
|
||||||
|
<td>@p.status</td>
|
||||||
|
<td>@p.order_time</td>
|
||||||
|
<td>@p.delivery_time</td>
|
||||||
|
</tr>
|
||||||
|
@end
|
||||||
|
</tbody>
|
||||||
|
</table> -->
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Binary file not shown.
|
@ -1,85 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Pannenkoekenwachtrij</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1>Welkom bij de pannenkoekenwachtrij</h1>
|
|
||||||
|
|
||||||
<form id="addPersonForm">
|
|
||||||
<p>Naam van de volgende <input type="text" name="name" maxlength=30></p>
|
|
||||||
<p>Specifieke opmerkingen <input type="text" name="remark" maxlength=50></p>
|
|
||||||
<p><input type="submit" value="Persoon toevoegen" id="addPersonButton"></p>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h2>Zie hieronder de lijst van personen die een pannenkoek willen</h2>
|
|
||||||
<table id="orderTable">
|
|
||||||
</table>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
function executeQuery(query, callback) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: '/execute',
|
|
||||||
contentType: "application/json",
|
|
||||||
data: JSON.stringify({
|
|
||||||
"lecode": query
|
|
||||||
}),
|
|
||||||
success: callback,
|
|
||||||
error: function(e) {
|
|
||||||
console.log("ERROR : ", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function start_bakken(id) {
|
|
||||||
executeQuery(`UPDATE orders SET status = 'aan_het_bakken' where id=${id}`, function(ign) {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function klaar(id) {
|
|
||||||
executeQuery(`UPDATE orders SET status = 'klaar' where id=${id}`, function(ign) {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function dismiss(id) {
|
|
||||||
executeQuery(`UPDATE orders SET status = 'dismissed' where id=${id}`, function(ign) {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTable() {
|
|
||||||
executeQuery(`SELECT id, name, remark, status from orders where status != 'dismissed'`, function(x) {
|
|
||||||
$('#orderTable').empty();
|
|
||||||
console.log(x);
|
|
||||||
for (row of x) {
|
|
||||||
console.log(row);
|
|
||||||
$('#orderTable').append(`<tr><td><button onclick="start_bakken(${row[0]})">Aan het bakken</button></td><td><button onclick="klaar(${row[0]})">Klaar</button></td><td><button onclick="dismiss(${row[0]})">Dismiss</button></td><th>${row[1] + " (" + row[2] + ")"}</th><td>${row[3]}</td></tr>`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
updateTable();
|
|
||||||
$("#addPersonButton").click(function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
var form = $("#addPersonForm").serializeArray();
|
|
||||||
var name = form[0]["value"];
|
|
||||||
var remark = form[1]["value"];
|
|
||||||
executeQuery(`INSERT INTO orders (name, remark) VALUES ('${name}', '${remark}')`, function(ign) {
|
|
||||||
updateTable();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
8
v.mod
Normal file
8
v.mod
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Module {
|
||||||
|
name: 'pannenkoekenwachtrij'
|
||||||
|
description: 'pannenkoekenvvachtrij'
|
||||||
|
version: '2.0.0'
|
||||||
|
license: 'MIT'
|
||||||
|
repo_url: 'https://git.zeus.gent/Kelder/pannenkoekenwachtrij'
|
||||||
|
dependencies: []
|
||||||
|
}
|
Loading…
Reference in a new issue