Files
ASPIC/bo_prompts.html
T

120 lines
3.9 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ASPIC — BackOffice — Prompts</title>
<link rel="icon" href="mevelia-icone.png">
<link rel="stylesheet" href="backoffice.css">
<style>
section{background:#111;border:1px solid #262626;border-radius:6px;padding:16px 18px;margin-bottom:18px;max-width:820px;}
section h2{font-size:13px;color:#ddd;font-weight:700;margin:0 0 2px;}
section .code{font-size:11px;color:#888;font-family:monospace;margin-bottom:10px;}
section textarea{width:100%;min-height:260px;resize:vertical;font-family:monospace;font-size:12px;line-height:1.5;}
.ligne-actions{display:flex;justify-content:space-between;align-items:center;margin-top:8px;}
.compteur{font-size:11px;color:#888;}
.msg{font-size:12px;min-height:14px;}
.msg.ok{color:#7be07b;}
.msg.ko{color:#e14a5c;}
</style>
</head>
<body>
<div id="bo-cadre">
<div id="bo-corps">
<nav id="bo-menu"></nav>
<main id="bo-contenu">
<h1>Prompts</h1>
<p class="sous-titre">Prompts système IA du projet — texte brut avec placeholders {{...}}, remplis par le code au moment de l'appel. Jamais consultable par un utilisateur final.</p>
<div id="liste-prompts">Chargement…</div>
</main>
</div>
<footer id="bo-pied"></footer>
</div>
<script src="backoffice.js"></script>
<script>
initBackoffice({ cibleEchap: 'backoffice.html' });
const conteneur = document.getElementById('liste-prompts');
function creerSection(p) {
const section = document.createElement('section');
const titre = document.createElement('h2');
titre.textContent = p.PMT_Libelle;
section.appendChild(titre);
const code = document.createElement('div');
code.className = 'code';
code.textContent = p.PMT_Code;
section.appendChild(code);
const texte = document.createElement('textarea');
texte.spellcheck = false;
texte.value = p.PMT_Texte || '';
section.appendChild(texte);
const ligneActions = document.createElement('div');
ligneActions.className = 'ligne-actions';
const compteur = document.createElement('span');
compteur.className = 'compteur';
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'principal';
btn.textContent = 'Enregistrer';
ligneActions.appendChild(compteur);
ligneActions.appendChild(btn);
section.appendChild(ligneActions);
const msg = document.createElement('div');
msg.className = 'msg';
section.appendChild(msg);
function majCompteur() {
compteur.textContent = texte.value.length.toLocaleString('fr-FR') + ' caractères';
}
texte.addEventListener('input', majCompteur);
majCompteur();
btn.addEventListener('click', async function () {
btn.disabled = true;
msg.textContent = ''; msg.className = 'msg';
try {
const r = await fetch('prompts.php', {
method: 'PUT', headers: {'Content-Type':'application/json'},
body: JSON.stringify({ PMT_Code: p.PMT_Code, PMT_Texte: texte.value })
});
const data = await r.json();
btn.disabled = false;
if (!r.ok) { msg.textContent = data.error || 'Erreur'; msg.className = 'msg ko'; return; }
msg.textContent = 'Enregistré.'; msg.className = 'msg ok';
} catch (e) {
btn.disabled = false;
msg.textContent = 'Erreur réseau'; msg.className = 'msg ko';
}
});
return section;
}
async function chargerPrompts() {
try {
const r = await fetch('prompts.php');
const data = await r.json();
if (!r.ok) { conteneur.textContent = data.error || 'Erreur'; return; }
const prompts = data.prompts || [];
conteneur.innerHTML = '';
if (!prompts.length) {
conteneur.innerHTML = '<p style="color:#666;font-size:12px;">Aucun prompt.</p>';
return;
}
prompts.forEach(function (p) { conteneur.appendChild(creerSection(p)); });
} catch (e) {
conteneur.textContent = 'Erreur réseau';
}
}
chargerPrompts();
</script>
</body>
</html>