Files
Alfredv2/alfred/app/static/js/alfred-identity-glass.js
T

61 lines
2.9 KiB
JavaScript

/* Identity editing: admin-protected API, optimistic revision checks, no HTML injection. */
(() => {
'use strict';
const $=id=>document.getElementById(id);
let csrf='',revision='',dirty=false,busy=false;
const msg=(s,error=false,id='idMessage')=>{const e=$(id);e.textContent=s;e.classList.toggle('error',error);};
const setName=name=>{
const n=String(name||'Assistant').trim();
const initial=Array.from(n)[0]?.toLocaleUpperCase('fr-FR')||'A';
$('idName').textContent=n;$('idInitial').textContent=initial;
$('idActiveName').textContent=n;$('idAvatar').textContent=initial;
document.title='Identité · '+n;
};
function updateCount(){$('idCount').textContent=$('idText').value.length.toLocaleString('fr-FR')+' caractères';}
async function jsonFetch(url,options={}){
const r=await fetch(url,{credentials:'same-origin',cache:'no-store',...options});
const d=await r.json().catch(()=>({}));
if(!r.ok)throw Error(d.error||'Erreur HTTP '+r.status);
return d;
}
async function auth(){
const a=await jsonFetch('/api/control/auth');
csrf=a.csrf||'';
$('idLoginPanel').hidden=!!a.authenticated;
$('idEditor').hidden=!a.authenticated;
$('idBadge').textContent=a.authenticated?'Administrateur connecté':'Connexion requise';
$('idBadge').classList.toggle('ok',!!a.authenticated);
if(a.authenticated)await load();
}
async function load(){
try{
const d=await jsonFetch('/api/control/identity');
$('idText').value=d.text;revision=d.revision;dirty=false;
setName(d.name);updateCount();msg('Document chargé.');
}catch(e){msg(e.message,true);}
}
$('idLoginForm').addEventListener('submit',async e=>{
e.preventDefault();
try{
await jsonFetch('/api/control/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:$('idPassword').value})});
$('idPassword').value='';await auth();
}catch(err){msg(err.message,true,'idLoginMessage');}
});
$('idText').addEventListener('input',()=>{dirty=true;updateCount();msg('Modifications non enregistrées.');});
$('idSave').addEventListener('click',async()=>{
if(busy||!revision)return;
busy=true;$('idSave').disabled=true;
try{
const d=await jsonFetch('/api/control/identity',{
method:'POST',headers:{'Content-Type':'application/json','X-Alfred-CSRF':csrf},
body:JSON.stringify({text:$('idText').value,revision})
});
revision=d.revision;dirty=false;msg(d.updated?'Identité enregistrée. Nouvelle version sauvegardée.':'Aucun changement à enregistrer.');
}catch(e){msg(e.message,true);}
finally{busy=false;$('idSave').disabled=false;}
});
$('idReload').addEventListener('click',()=>{if(dirty&&!confirm('Abandonner les modifications non enregistrées ?'))return;load();});
window.addEventListener('beforeunload',event=>{if(dirty){event.preventDefault();event.returnValue='';}});
auth().catch(e=>{msg(e.message,true,'idLoginMessage');$('idLoginPanel').hidden=false;});
})();