format_standup_text + _standup_data (journal de la veille, focus du jour, vieillissantes QA/Révision); page /standup copiable, /api/standup; inclusion optionnelle au briefing ntfy (KANBANTE_BRIEFING_INCLUDE_STANDUP).
81 lines
4.6 KiB
HTML
81 lines
4.6 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>
|
|
<header class="app-header">
|
|
<div class="brand">
|
|
<a href="/" class="logo" aria-label="Kanbante — accueil"><span class="logo-mark">📋</span><span class="gradient-text">Kanbante</span></a>
|
|
<span class="crumb"><span class="sep">/</span> 📊 <strong>Briefing</strong></span>
|
|
</div>
|
|
<nav class="nav-pills">
|
|
<a href="/" class="nav-pill">🏠 Projets</a>
|
|
<a href="/focus" class="nav-pill">🎯 Focus</a>
|
|
<a href="/today" class="nav-pill">🌅 Aujourd'hui</a>
|
|
<a href="/my" class="nav-pill">👤 Mes issues</a>
|
|
<a href="/activity" class="nav-pill">📰 Activité</a>
|
|
<a href="/search" class="nav-pill">🔍 Recherche</a>
|
|
<a href="/capture" class="nav-pill">⚡ Capture</a>
|
|
<a href="/digest" class="nav-pill">🧠 Digest</a>
|
|
<a href="/forecast" class="nav-pill">🔮 Prévisions</a>
|
|
<a href="/rules" class="nav-pill">⚙️ Règles</a>
|
|
<a href="/wall" class="nav-pill">🖥️ Wallboard</a>
|
|
<button type="button" class="nav-pill palette-trigger" title="Palette de commandes (Ctrl+K)">⌨️ Ctrl K</button>
|
|
</nav>
|
|
</header>
|
|
|
|
<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>
|