Files
turf_saas/agent_ia_config.html
2026-04-25 17:18:43 +02:00

198 lines
9.7 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agent IA - Configuration</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f0f23; color: #eee; min-height: 100vh; }
header { background: linear-gradient(90deg, #1a1a2e, #0f3460); padding: 15px 20px; border-bottom: 2px solid #00d9ff; display: flex; align-items: center; gap: 15px; }
header a { color: #888; text-decoration: none; font-size: 14px; }
header a:hover { color: #00d9ff; }
header h1 { font-size: 18px; background: linear-gradient(90deg, #00d9ff, #e94560); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.container { max-width: 700px; margin: 30px auto; padding: 0 20px; }
.card { background: #161b22; border: 1px solid #30363d; border-radius: 12px; padding: 24px; margin-bottom: 20px; }
.card h2 { font-size: 16px; margin-bottom: 16px; color: #00d9ff; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 13px; color: #888; margin-bottom: 6px; }
.form-group select, .form-group input { width: 100%; padding: 10px 12px; background: #0d1117; border: 1px solid #30363d; border-radius: 8px; color: #eee; font-size: 14px; outline: none; }
.form-group select:focus, .form-group input:focus { border-color: #00d9ff; }
.btn { padding: 10px 20px; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s; }
.btn-danger { background: #d23232; color: #fff; }
.btn-danger:hover { background: #b82828; }
.btn-danger:disabled { background: #30363d; color: #666; cursor: not-allowed; }
.info { padding: 12px 16px; background: rgba(0,217,255,0.08); border: 1px solid rgba(0,217,255,0.2); border-radius: 8px; font-size: 13px; color: #aaa; margin-bottom: 16px; }
.success { padding: 12px 16px; background: rgba(40,167,69,0.15); border: 1px solid rgba(40,167,69,0.3); border-radius: 8px; font-size: 13px; color: #6f6; display: none; }
.error { padding: 12px 16px; background: rgba(210,50,50,0.15); border: 1px solid rgba(210,50,50,0.3); border-radius: 8px; font-size: 13px; color: #f88; display: none; }
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.stat { background: #0d1117; border-radius: 8px; padding: 16px; text-align: center; }
.stat-value { font-size: 24px; font-weight: bold; color: #00d9ff; }
.stat-label { font-size: 11px; color: #666; margin-top: 4px; text-transform: uppercase; }
.home-btn{position:fixed;top:10px;left:10px;z-index:9999;background:linear-gradient(135deg,#00d9ff,#7b2cbf);color:#fff;border:none;border-radius:8px;padding:10px 15px;font-size:14px;cursor:pointer;text-decoration:none;display:flex;align-items:center;gap:8px;box-shadow:0 2px 10px rgba(0,217,255,0.3);transition:all 0.3s;font-family:-apple-system,BlinkMacSystemFont,sans-serif}.home-btn:hover{transform:translateY(-2px);box-shadow:0 4px 15px rgba(0,217,255,0.5)}
</style>
</head>
<body>
<a href="https://portal-kolifee.duckdns.org/" class="home-btn" title="Retour au portail"><span style="font-size:18px">🏠</span><span>Accueil</span></a>
<header>
<a href="/agent-ia">&#8592; Retour</a>
<h1>Configuration - Gestion de l'historique</h1>
</header>
<div class="container">
<div class="card">
<h2>Statistiques</h2>
<div class="stats" id="stats">
<div class="stat"><div class="stat-value" id="total-sessions">-</div><div class="stat-label">Sessions</div></div>
<div class="stat"><div class="stat-value" id="total-messages">-</div><div class="stat-label">Messages</div></div>
</div>
</div>
<div class="card">
<h2>Supprimer l'historique</h2>
<div class="info">
Cette action supprimera définitivement les messages plus anciens que la période sélectionnée. Les sessions vides seront également supprimées.
</div>
<div class="form-group">
<label>Workflow cible</label>
<select id="workflow-select"></select>
</div>
<div class="form-group">
<label>Période de rétention</label>
<select id="days-select">
<option value="7">7 jours</option>
<option value="14">14 jours</option>
<option value="30" selected>30 jours</option>
<option value="60">60 jours</option>
<option value="90">90 jours</option>
<option value="180">6 mois</option>
<option value="365">1 an</option>
</select>
</div>
<button class="btn btn-danger" id="cleanup-btn" onclick="cleanup()">Supprimer les messages anciens</button>
<div class="success" id="success-msg"></div>
<div class="error" id="error-msg"></div>
</div>
<div class="card">
<h2>Supprimer toutes les conversations</h2>
<div class="info" style="border-color: rgba(210,50,50,0.3); background: rgba(210,50,50,0.08);">
Attention : cette action est irréversible. Toutes les sessions et messages du workflow sélectionné seront supprimés.
</div>
<div class="form-group">
<label>Workflow cible</label>
<select id="workflow-select-all"></select>
</div>
<button class="btn btn-danger" onclick="deleteAll()">Tout supprimer</button>
</div>
</div>
<script>
let workflows = [];
async function loadWorkflows() {
try {
const resp = await fetch('/api/chat/workflows');
workflows = await resp.json();
const opts = workflows.map(w => `<option value="${w.slug}">${w.name}</option>`).join('');
document.getElementById('workflow-select').innerHTML = opts;
document.getElementById('workflow-select-all').innerHTML = opts;
loadStats();
} catch (e) {
console.error('Erreur:', e);
}
}
async function loadStats() {
const wf = document.getElementById('workflow-select').value;
if (!wf) return;
try {
const sessions = await (await fetch(`/api/chat/sessions?workflow=${wf}`)).json();
let totalMsg = 0;
for (const s of sessions) {
const msgs = await (await fetch(`/api/chat/history?session_id=${s.session_id}&workflow=${wf}`)).json();
totalMsg += msgs.length;
}
document.getElementById('total-sessions').textContent = sessions.length;
document.getElementById('total-messages').textContent = totalMsg;
} catch (e) {}
}
async function cleanup() {
const wf = document.getElementById('workflow-select').value;
const days = parseInt(document.getElementById('days-select').value);
const btn = document.getElementById('cleanup-btn');
const successEl = document.getElementById('success-msg');
const errorEl = document.getElementById('error-msg');
successEl.style.display = 'none';
errorEl.style.display = 'none';
btn.disabled = true;
btn.textContent = 'Suppression...';
try {
const resp = await fetch('/api/chat/cleanup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ workflow: wf, days: days })
});
const data = await resp.json();
if (data.error) throw new Error(data.error);
successEl.textContent = `${data.deleted} messages supprimés.`;
successEl.style.display = 'block';
loadStats();
} catch (e) {
errorEl.textContent = 'Erreur: ' + e.message;
errorEl.style.display = 'block';
} finally {
btn.disabled = false;
btn.textContent = 'Supprimer les messages anciens';
}
}
async function deleteAll() {
if (!confirm('Êtes-vous sûr de vouloir supprimer TOUTES les conversations de ce workflow ?')) return;
if (!confirm('Cette action est IRRÉVERSIBLE. Confirmer ?')) return;
const wf = document.getElementById('workflow-select-all').value;
const successEl = document.getElementById('success-msg');
const errorEl = document.getElementById('error-msg');
successEl.style.display = 'none';
errorEl.style.display = 'none';
try {
const sessions = await (await fetch(`/api/chat/sessions?workflow=${wf}`)).json();
let deleted = 0;
for (const s of sessions) {
await fetch(`/api/chat/session?session_id=${s.session_id}&workflow=${wf}`, { method: 'DELETE' });
deleted++;
}
successEl.textContent = `${deleted} sessions supprimées.`;
successEl.style.display = 'block';
loadStats();
} catch (e) {
errorEl.textContent = 'Erreur: ' + e.message;
errorEl.style.display = 'block';
}
}
loadWorkflows();
</script>
</body>
</html>