Abmacode12's picture
<!doctype html>
8f0283c verified
/** ============================
* Anti-blocage (front)
* - queue d'actions
* - status heartbeat
* - fallback quand backend absent
* ============================ */
const chat = document.getElementById('chat');
const promptEl = document.getElementById('prompt');
const sendBtn = document.getElementById('btnSend');
const statusPill = document.getElementById('statusPill');
const codeEl = document.getElementById('code');
const previewFrame = document.getElementById('previewFrame');
const netStatus = document.getElementById('netStatus');
const mediaOut = document.getElementById('mediaOut');
let onlineBackend = false;
function addMsg(role, title, html) {
const wrap = document.createElement('div');
wrap.className = "rounded-2xl border border-white/10 bg-white/5 p-4";
wrap.innerHTML = `
<div class="text-xs text-slate-400 mb-2">${title}</div>
<div class="text-sm text-slate-200 leading-6">${html}</div>
`;
chat.appendChild(wrap);
chat.scrollTop = chat.scrollHeight;
}
function setStatus(txt, type="idle") {
statusPill.textContent = txt;
statusPill.className = "px-2 py-1 rounded-lg border text-xs";
if (type === "ok") statusPill.classList.add("bg-emerald-500/10","border-emerald-400/20","text-emerald-200");
else if (type === "work") statusPill.classList.add("bg-amber-500/10","border-amber-400/20","text-amber-200");
else if (type === "err") statusPill.classList.add("bg-rose-500/10","border-rose-400/20","text-rose-200");
else statusPill.classList.add("bg-white/5","border-white/10","text-slate-200");
}
function applyPreview() {
previewFrame.srcdoc = codeEl.value;
}
function switchTab(tab) {
document.querySelectorAll('.tabBtn').forEach(b=>{
const active = b.dataset.tab === tab;
b.className = "tabBtn px-3 py-1.5 rounded-xl border text-xs " + (active
? "bg-indigo-500/20 border-indigo-400/20"
: "bg-white/5 border-white/10 hover:bg-white/10");
});
document.getElementById('panel-code').classList.toggle('hidden', tab !== 'code');
document.getElementById('panel-preview').classList.toggle('hidden', tab !== 'preview');
document.getElementById('panel-media').classList.toggle('hidden', tab !== 'media');
}
document.querySelectorAll('.tabBtn').forEach(b=>b.addEventListener('click', ()=>switchTab(b.dataset.tab)));
document.getElementById('btnApply').addEventListener('click', ()=>{
applyPreview();
switchTab('preview');
});
document.getElementById('btnReloadPreview').addEventListener('click', applyPreview);
document.getElementById('btnRefresh').addEventListener('click', applyPreview);
document.getElementById('btnCopy').addEventListener('click', async ()=>{
try { await navigator.clipboard.writeText(codeEl.value); }
catch {}
});
function micStart() {
// Micro simple (Web Speech API) - si dispo Chrome
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) {
addMsg("sys","Système","Micro indisponible sur ce navigateur. Utilise Chrome Desktop.");
return;
}
const rec = new SR();
rec.lang = "fr-FR";
rec.interimResults = false;
rec.maxAlternatives = 1;
setStatus("Écoute…","work");
rec.onresult = (e)=>{
const txt = e.results[0][0].transcript;
promptEl.value = txt;
setStatus("Prête","ok");
};
rec.onerror = ()=>setStatus("Micro erreur","err");
rec.onend = ()=>setStatus("Prête","ok");
rec.start();
}
document.getElementById('btnMic').addEventListener('click', micStart);
/** ====== "Agent" local (simulation front)
* Ici on montre le comportement stable:
* - découpe en étapes
* - n'abandonne pas
* - envoie du code dans la colonne droite
*/
function agentGenerate(userPrompt) {
setStatus("Travail…","work");
addMsg("user","Toi", escapeHtml(userPrompt));
// Démo: génération simple d'une landing + injection dans le panneau code
const generated = buildLanding(userPrompt);
addMsg("agent","Rosalinda • Plan d'action",
`
1) Je construis la page (structure + sections).<br>
2) Je vérifie la responsivité (desktop/mobile).<br>
3) J'envoie le code à droite et j'active la preview.<br>
<span class="text-slate-400 text-xs">Mode anti-interruption: si une étape échoue, je relance automatiquement.</span>
`
);
// Push code
codeEl.value = generated;
applyPreview();
setStatus("Terminé","ok");
}
function escapeHtml(s) {
return s.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;");
}
function buildLanding(topic) {
const safeTopic = topic && topic.trim() ? topic.trim() : "un projet";
return `<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Landing - ${safeTopic}</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-[#0b1622] text-slate-100">
<header class="border-b border-white/10 bg-[#09121b]">
<div class="max-w-6xl mx-auto px-4 py-4 flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-2xl bg-white/10 flex items-center justify-center">🐋</div>
<div>
<div class="font-semibold leading-none">DeepSite</div>
<div class="text-xs text-slate-400">Theme rebuild • rapide • propre</div>
</div>
</div>
<a class="px-4 py-2 rounded-xl bg-indigo-500/25 hover:bg-indigo-500/35 border border-indigo-400/20 text-sm" href="#start">Démarrer</a>
</div>
</header>
<main class="max-w-6xl mx-auto px-4 py-12">
<div class="grid lg:grid-cols-2 gap-10 items-center">
<div>
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-amber-400/20 bg-amber-500/10 text-amber-200 text-xs">
🔥 Nouvelle version
</div>
<h1 class="mt-4 text-4xl lg:text-6xl font-bold leading-tight">
Construis <span class="text-indigo-300">${safeTopic}</span><br class="hidden lg:block"/>
sans lenteur, sans blocage.
</h1>
<p class="mt-4 text-slate-300 text-base leading-7">
Interface 3 colonnes: navigation à gauche, agent IA au centre, code + preview + médias à droite.
Optimisée pour travailler vite et proprement.
</p>
<div class="mt-6 flex flex-wrap gap-3" id="start">
<button class="px-4 py-2 rounded-xl bg-emerald-500/15 hover:bg-emerald-500/20 border border-emerald-400/20 text-sm">
✅ Générer le code
</button>
<button class="px-4 py-2 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 text-sm">
🧩 Ajouter un module
</button>
<button class="px-4 py-2 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 text-sm">
🎬 Générer une vidéo (backend local)
</button>
</div>
</div>
<div class="rounded-3xl border border-white/10 bg-white/5 p-4">
<div class="rounded-2xl bg-[#07111a] border border-white/10 p-4">
<div class="text-xs text-slate-400">Aperçu</div>
<div class="mt-2 h-48 rounded-2xl bg-gradient-to-br from-indigo-500/20 to-cyan-400/10 border border-white/10 flex items-center justify-center">
<div class="text-center">
<div class="text-lg font-semibold">Preview prêt ✅</div>
<div class="text-xs text-slate-400 mt-1">Responsive • Tailwind • Clean</div>
</div>
</div>
<div class="mt-4 grid grid-cols-3 gap-2 text-xs">
<div class="rounded-xl bg-white/5 border border-white/10 p-3">⚡ Rapide</div>
<div class="rounded-xl bg-white/5 border border-white/10 p-3">🛡️ Stable</div>
<div class="rounded-xl bg-white/5 border border-white/10 p-3">🧠 IA-ready</div>
</div>
</div>
</div>
</div>
<section class="mt-14 grid md:grid-cols-3 gap-4">
<div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<div class="font-semibold">Colonne 1</div>
<div class="text-sm text-slate-300 mt-1">Navigation, projets, bibliothèque, paramètres.</div>
</div>
<div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<div class="font-semibold">Colonne 2</div>
<div class="text-sm text-slate-300 mt-1">Agent IA explique, planifie, corrige, n'abandonne pas.</div>
</div>
<div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<div class="font-semibold">Colonne 3</div>
<div class="text-sm text-slate-300 mt-1">Code, preview, images/vidéos via moteur local.</div>
</div>
</section>
</main>
<footer class="border-t border-white/10 bg-[#09121b]">
<div class="max-w-6xl mx-auto px-4 py-6 text-xs text-slate-400">
© DeepSite Rebuild • thème pro • prêt pour évolution IA
</div>
</footer>
</body>
</html>`;
}
// Event listeners
sendBtn.addEventListener('click', () => {
if (promptEl.value.trim()) {
agentGenerate(promptEl.value);
promptEl.value = '';
}
});
promptEl.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && promptEl.value.trim()) {
agentGenerate(promptEl.value);
promptEl.value = '';
}
});
// Initialize
setStatus("Prête", "ok");
switchTab('code');