Partiel _header.html unique pour les 19 pages (fin des copies qui dérivaient): desktop une ligne — primaires + menu Plus + Ctrl K, page active déduite du gabarit dans render(); mobile ≤900px burger + panneau ≥44px, Échap/clic extérieur; wallboard sans header et triage sur le même partiel. nav.js partagé.
62 lines
3.4 KiB
HTML
62 lines
3.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr" data-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token }}">
|
|
<title>Briefing — Kanbante</title>
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📊</text></svg>">
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
{% include "_header.html" %}
|
|
|
|
<main class="focus-main">
|
|
<p class="focus-intro">Le briefing du <strong>{{ data.date }}</strong> — le même contenu que celui poussé sur ntfy.</p>
|
|
|
|
<div class="stat-tiles briefing-tiles">
|
|
<div class="stat-tile"><span class="stat-num">{{ data.focus_total }}</span><span class="stat-label">en cours / révision</span></div>
|
|
<div class="stat-tile"><span class="stat-num">{{ data.activity_24h.closed }}</span><span class="stat-label">fermées · 24 h</span></div>
|
|
<div class="stat-tile"><span class="stat-num">{{ data.activity_24h.moved }}</span><span class="stat-label">déplacements · 24 h</span></div>
|
|
<div class="stat-tile"><span class="stat-num">{{ data.aging|length }}</span><span class="stat-label">cartes vieillissantes</span></div>
|
|
</div>
|
|
|
|
<section class="briefing-card">
|
|
<h2>📄 Contenu du briefing</h2>
|
|
<pre class="briefing-text">{{ text }}</pre>
|
|
</section>
|
|
|
|
<section class="briefing-card">
|
|
<h2>📲 Envoi ntfy</h2>
|
|
{% if ntfy_configured %}
|
|
<p class="notes-hint">ntfy est configuré. {% if briefing_time %}Envoi automatique chaque jour à <strong>{{ briefing_time }}</strong> (heure du serveur).{% else %}Aucune heure d'envoi automatique (<code>KANBANTE_BRIEFING_TIME</code> non défini).{% endif %}{% if last_sent %} Dernier envoi : {{ last_sent }}.{% endif %}</p>
|
|
<form id="briefing-send-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<button type="submit" class="btn-save">📤 Envoyer maintenant via ntfy</button>
|
|
</form>
|
|
<p id="briefing-status" class="notes-hint"></p>
|
|
{% else %}
|
|
<p class="notes-hint">Pour recevoir ce briefing sur votre téléphone, définissez <code>KANBANTE_NTFY_URL</code> (ex. <code>https://ntfy.sh</code> ou votre ntfy auto-hébergé), <code>KANBANTE_NTFY_TOPIC</code> et, pour l'envoi automatique, <code>KANBANTE_BRIEFING_TIME=07:30</code>, puis redémarrez Kanbante.</p>
|
|
{% endif %}
|
|
</section>
|
|
</main>
|
|
|
|
<footer>
|
|
Kanbante v{{ version }} · briefing quotidien
|
|
</footer>
|
|
<script src="/static/js/live.js" defer></script>
|
|
<script>
|
|
document.getElementById('briefing-send-form')?.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const status = document.getElementById('briefing-status');
|
|
status.textContent = 'Envoi en cours...';
|
|
const r = await fetch('/api/briefing/send', { method: 'POST', body: new FormData(e.target) });
|
|
const data = await r.json().catch(() => ({}));
|
|
status.textContent = data.ok ? '✅ Briefing envoyé sur ntfy.' : '❌ ' + (data.error || ('HTTP ' + r.status));
|
|
});
|
|
</script>
|
|
{% include "_palette.html" %}
|
|
<script src="/static/js/palette.js" defer></script>
|
|
</body>
|
|
</html>
|