add infokiosk page

This commit is contained in:
miklo 2025-12-04 04:14:03 +01:00
parent cc6c7e83b8
commit 9e356b9da4
3 changed files with 165 additions and 9 deletions

View File

@ -40,7 +40,7 @@ def close_db(exc):
db.close() db.close()
# Main display for clients # Main display for clients/mobile
@app.route("/") @app.route("/")
def index(): def index():
db = get_db() db = get_db()
@ -52,19 +52,35 @@ def index():
return render_template("index.html", current=current) return render_template("index.html", current=current)
# Main display for infokiosk
@app.route("/infokiosk")
def infokiosk():
db = get_db()
cur = db.execute(
"SELECT number FROM items WHERE status='called' ORDER BY id DESC LIMIT 1"
)
row = cur.fetchone()
current = row["number"] if row else ""
return render_template("infokiosk.html", current=current)
# API endpoint used by clients to poll current number (JSON) # API endpoint used by clients to poll current number (JSON)
@app.route("/current") @app.route("/current")
def current_api(): def current_api():
db = get_db() db = get_db()
cur_called = db.execute("SELECT number FROM items WHERE status='called' ORDER BY id").fetchall() cur_called = db.execute(
"SELECT number FROM items WHERE status='called' ORDER BY id"
).fetchall()
nums = [r["number"] for r in cur_called] nums = [r["number"] for r in cur_called]
cur_wait = db.execute("SELECT COUNT(*) AS cnt FROM items WHERE status='waiting'").fetchone() cur_wait = db.execute(
"SELECT COUNT(*) AS cnt FROM items WHERE status='waiting'"
).fetchone()
waiting_count = cur_wait["cnt"] if cur_wait else 0 waiting_count = cur_wait["cnt"] if cur_wait else 0
return jsonify(current=nums, waiting=waiting_count) return jsonify(current=nums, waiting=waiting_count)
# Admin UI: start/reset system by providing count of tickets (1..N) # Admin UI: start/reset system by providing count of tickets (1..N)
# @app.route("/admin", methods=["GET", "POST"]) # @app.route("/admin", methods=[":wGET", "POST"])
def admin(): def admin():
db = get_db() db = get_db()
@ -72,7 +88,9 @@ def admin():
action = request.form.get("action") action = request.form.get("action")
if action == "add": if action == "add":
# dodaj nowy numer na końcu puli # dodaj nowy numer na końcu puli
cur = db.execute("SELECT number FROM items ORDER BY id DESC LIMIT 1").fetchone() cur = db.execute(
"SELECT number FROM items ORDER BY id DESC LIMIT 1"
).fetchone()
if cur: if cur:
try: try:
last = int(cur["number"]) last = int(cur["number"])
@ -81,23 +99,34 @@ def admin():
new = last + 1 new = last + 1
else: else:
new = 1 new = 1
db.execute("INSERT INTO items (number, status) VALUES (?, 'waiting')", (str(new),)) db.execute(
"INSERT INTO items (number, status) VALUES (?, 'waiting')", (str(new),)
)
db.commit() db.commit()
elif action == "call": elif action == "call":
num = request.form.get("num") num = request.form.get("num")
db.execute("UPDATE items SET status='called' WHERE number=? AND status='waiting'", (num,)) db.execute(
"UPDATE items SET status='called' WHERE number=? AND status='waiting'",
(num,),
)
db.commit() db.commit()
elif action == "done": elif action == "done":
num = request.form.get("num") num = request.form.get("num")
db.execute("UPDATE items SET status='done' WHERE number=? AND status='called'", (num,)) db.execute(
"UPDATE items SET status='done' WHERE number=? AND status='called'",
(num,),
)
db.commit() db.commit()
elif action == "return": elif action == "return":
num = request.form.get("num") num = request.form.get("num")
if num: if num:
db.execute("UPDATE items SET status='waiting' WHERE number=? AND status='called'", (num,)) db.execute(
"UPDATE items SET status='waiting' WHERE number=? AND status='called'",
(num,),
)
db.commit() db.commit()
elif action == "reset": elif action == "reset":
@ -122,6 +151,7 @@ def admin():
done=[r["number"] for r in cur_done], done=[r["number"] for r in cur_done],
) )
app.add_url_rule(ADMIN_PATH, endpoint="admin", view_func=admin, methods=["GET", "POST"]) app.add_url_rule(ADMIN_PATH, endpoint="admin", view_func=admin, methods=["GET", "POST"])

BIN
src/static/background.mp4 Normal file

Binary file not shown.

View File

@ -0,0 +1,126 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Informacje</title>
<style>
:root{height:100%;}
html,body{height:100%;margin:0;font-family:Helvetica,Arial;color:#000;}
.viewport{display:flex;flex-direction:column;height:100vh;min-height:100%;}
.video-area{
flex:0 0 85%;
position:relative;
overflow:hidden;
background:#000;
}
.info-bar{
flex:0 0 15%;
background:#fdb515;
color:#000;
display:flex;
align-items:center;
box-sizing:border-box;
height:15vh;
min-height:50px;
padding-left:4vh;
padding-right:4vh;
}
.video-area video{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
height:100%;
width:auto;
object-fit:cover;
}
.info-bar, .info-bar .info-left, .info-bar .info-right {
font-size:5vh;
line-height:1;
}
.info-left, .info-right{
display:flex;
align-items:center;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.info-left{flex:1 1 70%; font-weight:700;}
.info-right{flex:0 0 auto; margin-left:16px; font-weight:700;}
.num-inline{
display:inline-block;
margin-left:1vh;
padding:1.6vh 1.2vh;
border:0.4vh solid #000;
border-radius:0.8vh;
background:transparent;
font-weight:700;
line-height:1;
vertical-align:middle;
}
@media (max-width:700px){
.video-area{flex-basis:70%}
}
</style>
<script>
async function fetchCurrent(){
try{
const r = await fetch('/current', {cache: 'no-store'});
const j = await r.json();
// update inline list in info bar
const numList = document.getElementById('num-list');
const nums = j.current || [];
if(nums.length === 0){
numList.innerHTML = '-';
} else {
numList.innerHTML = nums.map(n => '<span class="num-inline">' + String(n) + '</span>').join(' ');
}
// update waiting count
document.getElementById('waiting-count').textContent = (j.waiting != null) ? j.waiting : '0';
}catch(e){
console.error('fetchCurrent error', e);
}
}
window.addEventListener('load', () => {
fetchCurrent();
// poll time
setInterval(fetchCurrent, 5000);
});
</script>
</head>
<body>
<div class="viewport">
<div class="video-area">
<video id="bgvideo" autoplay loop playsinline>
<source src="{{ url_for('static', filename='background.mp4') }}" type="video/mp4">
</video>
</div>
<div class="info-bar">
<div id="info-left" class="info-left">
Zapraszamy z numerami: <span id="num-list">-</span>
</div>
<div class="info-right">
Oczekujących: <span id="waiting-count" style="margin-left:1vh;">0</span>
</div>
</div>
</div>
</body>
</html>