first commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}JH Photomaton{% endblock %}</title>
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% block navbar %}
|
||||
<nav class="navbar">
|
||||
<div class="navbar-brand">📷 <span>JH</span> Photomaton</div>
|
||||
<div class="navbar-links">
|
||||
{% block nav_links %}{% endblock %}
|
||||
</div>
|
||||
<div class="navbar-status" id="ws-status">
|
||||
<span class="dot dot-gray" id="ws-dot"></span>
|
||||
<span id="ws-label">Connexion…</span>
|
||||
</div>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Toast container -->
|
||||
<div class="toast-container" id="toasts"></div>
|
||||
|
||||
<script>
|
||||
// ── WebSocket global ─────────────────────────────────────────────────────────
|
||||
let ws = null;
|
||||
let wsReconnectTimer = null;
|
||||
|
||||
function connectWS() {
|
||||
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
ws = new WebSocket(`${proto}//${location.host}/ws`);
|
||||
|
||||
ws.onopen = () => {
|
||||
document.getElementById('ws-dot').className = 'dot dot-green';
|
||||
document.getElementById('ws-label').textContent = 'Connecté';
|
||||
clearTimeout(wsReconnectTimer);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
document.getElementById('ws-dot').className = 'dot dot-red';
|
||||
document.getElementById('ws-label').textContent = 'Déconnecté';
|
||||
wsReconnectTimer = setTimeout(connectWS, 3000);
|
||||
};
|
||||
|
||||
ws.onerror = () => ws.close();
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
try {
|
||||
const msg = JSON.parse(e.data);
|
||||
handleWsMessage(msg);
|
||||
} catch(err) {}
|
||||
};
|
||||
}
|
||||
|
||||
function handleWsMessage(msg) {
|
||||
// Override dans chaque page si besoin
|
||||
if (typeof onWsMessage === 'function') onWsMessage(msg);
|
||||
}
|
||||
|
||||
// ── Toast notifications ──────────────────────────────────────────────────────
|
||||
function showToast(text, type = 'info', duration = 4000) {
|
||||
const el = document.createElement('div');
|
||||
el.className = `toast ${type}`;
|
||||
el.textContent = text;
|
||||
document.getElementById('toasts').appendChild(el);
|
||||
setTimeout(() => el.remove(), duration);
|
||||
}
|
||||
|
||||
// ── API helper ───────────────────────────────────────────────────────────────
|
||||
async function api(method, url, body = null) {
|
||||
const opts = { method, headers: {} };
|
||||
if (body) {
|
||||
opts.headers['Content-Type'] = 'application/json';
|
||||
opts.body = JSON.stringify(body);
|
||||
}
|
||||
const r = await fetch(url, opts);
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
return r.json();
|
||||
}
|
||||
|
||||
connectWS();
|
||||
</script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user