Files
wevads-platform/public/hamid-fullscreen.php.backup3
2026-02-26 04:53:11 +01:00

391 lines
26 KiB
Plaintext
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
session_start();
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123");
$config = [];
try { $stmt = $pdo->query("SELECT config_key, config_value FROM admin.commonia_config"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $config[$row['config_key']] = $row['config_value']; } catch (Exception $e) {}
$defaultProvider = $config['default_provider'] ?? 'groq';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>HAMID - Assistant WEVADS</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
:root{--bg:#f8f8f8;--sidebar:#fff;--chat:#fff;--text:#1a1a1a;--muted:#6b7280;--border:#e5e7eb;--primary:#06b6d4}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,sans-serif;background:var(--bg);color:var(--text);height:100vh;overflow:hidden}
.app{display:flex;height:100vh}
.sidebar{width:260px;background:var(--sidebar);border-right:1px solid var(--border);display:flex;flex-direction:column}
.sidebar-header{padding:1rem}
.new-chat{width:100%;padding:.75rem 1rem;background:linear-gradient(135deg,#06b6d4,#3b82f6);color:#fff;border:none;border-radius:8px;cursor:pointer;display:flex;align-items:center;gap:.5rem}
.sidebar-section{padding:.5rem 1rem}
.sidebar-title{font-size:.7rem;font-weight:600;color:var(--muted);text-transform:uppercase;margin-bottom:.5rem}
.sidebar-item{display:flex;align-items:center;gap:.75rem;padding:.6rem .75rem;border-radius:6px;color:var(--text);text-decoration:none;font-size:.9rem}
.sidebar-item:hover{background:#f3f4f6}
.sidebar-footer{margin-top:auto;padding:1rem;border-top:1px solid var(--border)}
.sidebar-footer a{display:flex;align-items:center;gap:.5rem;padding:.5rem;color:var(--muted);text-decoration:none;font-size:.85rem}
.main{flex:1;display:flex;flex-direction:column}
.header{padding:.75rem 1.5rem;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}
.header-left{display:flex;align-items:center;gap:.75rem}
.logo{width:36px;height:36px;border-radius:8px;background:linear-gradient(135deg,#06b6d4,#3b82f6);display:flex;align-items:center;justify-content:center;font-size:1.2rem}
.header-right{display:flex;align-items:center;gap:.5rem}
.help-btn{padding:.5rem .75rem;border:1px solid var(--border);background:#fff;border-radius:8px;cursor:pointer}
.provider-select{position:relative}
.provider-btn{padding:.5rem 1rem;border:1px solid var(--border);background:#fff;border-radius:8px;cursor:pointer;display:flex;align-items:center;gap:.5rem}
.provider-btn .dot{width:8px;height:8px;border-radius:50%;background:#10b981}
.provider-menu{position:absolute;top:100%;right:0;margin-top:.5rem;background:#fff;border:1px solid var(--border);border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,.15);min-width:280px;z-index:100;display:none}
.provider-menu.show{display:block}
.provider-group{padding:.5rem}
.provider-group-title{padding:.5rem .75rem;font-size:.7rem;font-weight:600;text-transform:uppercase}
.provider-group-title.free{color:#10b981}
.provider-group-title.limited{color:#f59e0b}
.provider-group-title.paid{color:#ef4444}
.provider-option{display:flex;align-items:center;gap:.75rem;padding:.6rem .75rem;border-radius:8px;cursor:pointer}
.provider-option:hover{background:#f3f4f6}
.provider-option.active{background:#e0f2fe}
.provider-option .icon{font-size:1.25rem}
.provider-option .info{flex:1}
.provider-option .name{font-size:.9rem;font-weight:500}
.provider-option .desc{font-size:.75rem;color:var(--muted)}
.messages{flex:1;overflow-y:auto;padding:1.5rem}
.welcome{text-align:center;padding:3rem 1rem}
.welcome-icon{width:80px;height:80px;background:linear-gradient(135deg,#06b6d4,#3b82f6);border-radius:20px;display:flex;align-items:center;justify-content:center;margin:0 auto 1.5rem;font-size:2.5rem}
.welcome h2{margin-bottom:.75rem}
.welcome p{color:var(--muted);margin-bottom:2rem}
.quick-actions{display:flex;gap:.75rem;justify-content:center;flex-wrap:wrap}
.quick-btn{padding:.75rem 1.25rem;border:2px solid var(--border);background:#fff;border-radius:10px;cursor:pointer;display:flex;align-items:center;gap:.5rem}
.quick-btn:hover{border-color:var(--primary);background:#f0fdfa}
.msg{display:flex;gap:1rem;margin-bottom:1.5rem;max-width:900px;margin-left:auto;margin-right:auto}
.msg-user{justify-content:flex-end}
.msg-user .bubble{background:#f3f4f6;padding:.875rem 1rem;border-radius:16px 16px 4px 16px;max-width:70%}
.msg-assistant{align-items:flex-start}
.msg-assistant .avatar{width:32px;height:32px;background:linear-gradient(135deg,#06b6d4,#3b82f6);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:.9rem}
.msg-assistant .msg-wrap{flex:1;max-width:80%}
.msg-assistant .msg-content{line-height:1.6}
.msg-footer{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--border);font-size:.7rem;color:var(--muted);display:flex;gap:.4rem;flex-wrap:wrap}
.msg-footer .tag{padding:.2rem .5rem;border-radius:4px;background:#f3f4f6}
.msg-footer .tag.prov{background:#dbeafe;color:#1e40af}
.msg-footer .tag.kb{background:#d1fae5;color:#065f46}
.typing{display:none;padding:1rem 1.5rem;max-width:900px;margin:0 auto}
.typing.show{display:flex !important;align-items:center;gap:.75rem}
.typing-avatar{width:32px;height:32px;background:linear-gradient(135deg,#06b6d4,#3b82f6);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:.9rem}
.typing-dots{display:flex;gap:4px;padding:.75rem 1rem;background:#f3f4f6;border-radius:16px}
.typing-dots span{width:8px;height:8px;background:#94a3b8;border-radius:50%;animation:bounce 1.4s infinite}
.typing-dots span:nth-child(2){animation-delay:.2s}
.typing-dots span:nth-child(3){animation-delay:.4s}
@keyframes bounce{0%,80%,100%{transform:translateY(0)}40%{transform:translateY(-6px)}}
.input-area{padding:1rem 1.5rem 1.5rem;border-top:1px solid var(--border)}
.input-wrap{display:flex;gap:.5rem;max-width:900px;margin:0 auto;background:#fff;border:1px solid var(--border);border-radius:12px;padding:.5rem;align-items:flex-end}
.input-wrap:focus-within{border-color:var(--primary)}
.input-wrap textarea{flex:1;border:none;outline:none;resize:none;font-size:.95rem;padding:.5rem;max-height:120px}
.input-btn{width:40px;height:40px;background:none;border:none;color:var(--muted);cursor:pointer;border-radius:8px;font-size:1.1rem}
.input-btn:hover{background:#f3f4f6;color:var(--primary)}
.send-btn{width:40px;height:40px;background:linear-gradient(135deg,#06b6d4,#3b82f6);color:#fff;border:none;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}
#artPanel{position:fixed;right:-500px;top:0;width:500px;height:100vh;background:#fff;border-left:1px solid var(--border);display:flex;flex-direction:column;transition:right .3s;z-index:200}
#artPanel.open{right:0;box-shadow:-5px 0 30px rgba(0,0,0,.1)}
.art-header{padding:1rem;border-bottom:1px solid var(--border);display:flex;justify-content:space-between}
.art-close{background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--muted)}
#artContent{flex:1;overflow:auto;background:#f8fafc}
#artContent iframe{width:100%;height:100%;border:none}
.art-footer{padding:1rem;border-top:1px solid var(--border)}
.art-footer .btn{padding:.5rem 1rem;border:1px solid var(--border);background:#fff;border-radius:6px;text-decoration:none;color:var(--text);display:inline-flex;align-items:center;gap:.4rem}
.modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);z-index:300;align-items:center;justify-content:center}
.modal.show{display:flex}
.modal-content{background:#fff;border-radius:16px;padding:2rem;max-width:500px;width:90%}
.modal-content h3{margin-bottom:1rem}
.modal-content ul{margin:1rem 0;padding-left:1.5rem}
.modal-content li{margin-bottom:.5rem;color:var(--muted)}
.modal-content button{margin-top:1rem;padding:.75rem 1.5rem;background:var(--primary);color:#fff;border:none;border-radius:8px;cursor:pointer}
@media(max-width:768px){.sidebar{display:none}}
.msg-tag{display:inline-block;font-size:10px;padding:2px 6px;border-radius:4px;margin-left:4px}
.msg-tag.kb{background:#10b981;color:white}
.msg-tag.ia{background:#8b5cf6;color:white}
/* Tools Panel */
.tools-panel {
background: rgba(15, 23, 42, 0.95);
border: 1px solid #334155;
border-radius: 12px;
padding: 1rem;
margin: 0.5rem;
}
.tools-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.5rem;
}
.tool-btn {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
padding: 0.75rem 0.5rem;
background: linear-gradient(135deg, #1e293b, #0f172a);
border: 1px solid #334155;
border-radius: 8px;
color: #e2e8f0;
cursor: pointer;
transition: all 0.2s;
font-size: 0.75rem;
}
.tool-btn:hover {
border-color: #06b6d4;
background: linear-gradient(135deg, #1e3a5f, #0f172a);
transform: translateY(-2px);
}
.tool-btn .icon { font-size: 1.25rem; }
.tool-btn .label { color: #94a3b8; }
.tool-result {
background: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 0.75rem;
margin: 0.5rem 0;
font-family: monospace;
font-size: 0.8rem;
max-height: 200px;
overflow-y: auto;
}
.tool-result pre {
margin: 0;
white-space: pre-wrap;
color: #10b981;
}
.tool-header {
color: #06b6d4;
font-weight: bold;
margin-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.quick-actions {
display: flex;
gap: 0.5rem;
padding: 0.5rem;
overflow-x: auto;
border-top: 1px solid #334155;
}
.quick-action {
padding: 0.4rem 0.8rem;
background: rgba(6, 182, 212, 0.1);
border: 1px solid rgba(6, 182, 212, 0.3);
border-radius: 20px;
color: #06b6d4;
font-size: 0.7rem;
cursor: pointer;
white-space: nowrap;
transition: all 0.2s;
}
.quick-action:hover {
background: rgba(6, 182, 212, 0.2);
border-color: #06b6d4;
}
</style>
</head>
<body>
<div class="app">
<div class="sidebar">
<div class="sidebar-header"><button class="new-chat" onclick="newChat()"><i class="fas fa-plus"></i> Nouvelle conversation</button></div>
<div class="sidebar-section"><div class="sidebar-title">Outils</div><a href="/ia-tools-test.php" class="sidebar-item"><i class="fas fa-wrench"></i> Test Tools</a><a href="javascript:void(0)" onclick="toggleToolsPanel()" class="sidebar-item" style="background:linear-gradient(135deg,#06b6d4,#3b82f6);color:white"><i class="fas fa-cogs"></i> 🔧 Tools Système</a><a href="/ia-documents.php" class="sidebar-item"><i class="fas fa-folder"></i> Documents</a><a href="/ia-knowledge.php" class="sidebar-item"><i class="fas fa-brain"></i> Knowledge Base</a></div>
<div class="sidebar-footer"><a href="/ia-index.php"><i class="fas fa-th-large"></i> Index IA</a><a href="/hamid-brain-config.php"><i class="fas fa-cog"></i> Configuration</a></div>
</div>
<div class="main">
<div class="header">
<div class="header-left"><div class="logo">🧞</div><span style="font-weight:600">HAMID - Assistant WEVADS</span></div>
<div class="header-right">
<button class="help-btn" onclick="showHelp()"><i class="fas fa-question-circle"></i> Aide</button>
<div class="provider-select">
<button class="provider-btn" onclick="document.getElementById('providerMenu').classList.toggle('show')"><span class="dot"></span><span id="currentProvider"><?= ucfirst($defaultProvider) ?></span><i class="fas fa-chevron-down"></i></button>
<div class="provider-menu" id="providerMenu">
<div class="provider-group"><div class="provider-group-title free">✅ Gratuits Illimités</div>
<div class="provider-option" data-prov="ollama_mini" onclick="selProv('ollama_mini','Ollama Mini')"><span class="icon">⚡</span><div class="info"><div class="name">Ollama Mini</div><div class="desc">Local • Rapide</div></div></div>
<div class="provider-option" data-prov="ollama" onclick="selProv('ollama','Ollama Mistral')"><span class="icon">🦙</span><div class="info"><div class="name">Ollama Mistral</div><div class="desc">Local • 7B</div></div></div>
<div class="provider-option" data-prov="deepseek" onclick="selProv('deepseek','DeepSeek')"><span class="icon">🔮</span><div class="info"><div class="name">DeepSeek</div><div class="desc">Cloud • Intelligent</div></div></div>
<div class="provider-option" data-prov="cerebras" onclick="selProv('cerebras','Cerebras')"><span class="icon">🧠</span><div class="info"><div class="name">Cerebras</div><div class="desc">Ultra rapide</div></div></div>
<div class="provider-option" data-prov="hyperbolic" onclick="selProv('hyperbolic','Hyperbolic')"><span class="icon">🌀</span><div class="info"><div class="name">Hyperbolic</div><div class="desc">Llama 405B</div></div></div>
<div class="provider-option" data-prov="mistral" onclick="selProv('mistral','Mistral')"><span class="icon">🇫🇷</span><div class="info"><div class="name">Mistral</div><div class="desc">Français</div></div></div>
<div class="provider-option" data-prov="cohere" onclick="selProv('cohere','Cohere')"><span class="icon">🔶</span><div class="info"><div class="name">Cohere</div><div class="desc">Command-R+</div></div></div>
</div>
<div class="provider-group"><div class="provider-group-title limited">⚠️ Gratuits Limités</div>
<div class="provider-option" data-prov="groq" onclick="selProv('groq','Groq')"><span class="icon">🚀</span><div class="info"><div class="name">Groq</div><div class="desc">Ultra rapide</div></div></div>
<div class="provider-option" data-prov="gemini" onclick="selProv('gemini','Gemini')"><span class="icon">💎</span><div class="info"><div class="name">Gemini</div><div class="desc">Google</div></div></div>
</div>
<div class="provider-group"><div class="provider-group-title paid">💰 Payants</div>
<div class="provider-option" data-prov="claude" onclick="selProv('claude','Claude')"><span class="icon">🧠</span><div class="info"><div class="name">Claude</div><div class="desc">Anthropic</div></div></div>
<div class="provider-option" data-prov="chatgpt" onclick="selProv('chatgpt','ChatGPT')"><span class="icon">🤖</span><div class="info"><div class="name">ChatGPT</div><div class="desc">OpenAI GPT-4</div></div></div>
<div class="provider-option" data-prov="copilot" onclick="selProv('copilot','Copilot')"><span class="icon">🐙</span><div class="info"><div class="name">GitHub Copilot</div><div class="desc">Code Assistant</div></div></div>
</div></div></div></div></div>
<div class="messages" id="msgs">
<div class="welcome" id="welcome"><div class="welcome-icon">🧞</div><h2>Bonjour, je suis HAMID</h2><p>Assistant IA WEVADS avec génération de documents</p>
<div class="quick-actions">
<button class="quick-btn" onclick="sendQuick('Génère un PDF')"><i class="fas fa-file-pdf" style="color:#ef4444"></i> PDF</button>
<button class="quick-btn" onclick="sendQuick('Génère un document Word')"><i class="fas fa-file-word" style="color:#2563eb"></i> Word</button>
<button class="quick-btn" onclick="sendQuick('Génère un fichier Excel')"><i class="fas fa-file-excel" style="color:#16a34a"></i> Excel</button>
<button class="quick-btn" onclick="sendQuick('Génère une présentation')"><i class="fas fa-file-powerpoint" style="color:#ea580c"></i> PPT</button>
<button class="quick-btn" onclick="sendQuick('Génère un QR code')"><i class="fas fa-qrcode" style="color:#7c3aed"></i> QR</button>
</div></div></div>
<div class="typing" id="typing">
<div class="typing-avatar">🧞</div>
<div class="typing-dots"><span></span><span></span><span></span></div>
<span style="color:var(--muted);font-size:.9rem">Réflexion...</span>
</div>
<div class="input-area"><div class="input-wrap">
<button class="input-btn" onclick="document.getElementById('fileInput').click()" title="Fichier"><i class="fas fa-paperclip"></i></button>
<button class="input-btn" onclick="document.getElementById('imageInput').click()" title="Image"><i class="fas fa-image"></i></button>
<input type="file" id="fileInput" style="display:none" multiple accept=".pdf,.doc,.docx,.xls,.xlsx,.txt" onchange="handleFiles(this.files)">
<input type="file" id="imageInput" style="display:none" multiple accept="image/*,video/*" onchange="handleFiles(this.files)">
<textarea id="input" placeholder="Écrivez votre message..." rows="1" onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();send()}"></textarea>
<button class="send-btn" onclick="send()"><i class="fas fa-arrow-up"></i></button>
</div></div></div>
<div id="artPanel"><div class="art-header"><h3><i class="fas fa-file-alt"></i> <span id="artTitle">Document</span></h3><button class="art-close" onclick="closeArt()">×</button></div><div id="artContent"></div><div class="art-footer"><a id="artDL" href="#" class="btn" download><i class="fas fa-download"></i> Télécharger</a></div></div>
</div>
<div class="modal" id="helpModal"><div class="modal-content"><h3>🧞 Aide HAMID</h3><p><strong>Génération :</strong></p><ul><li>PDF - "Génère un PDF"</li><li>Word - "Génère un document Word"</li><li>Excel - "Génère un fichier Excel"</li><li>PPT - "Génère une présentation"</li><li>QR - "Génère un QR code"</li></ul><p>📎 Fichiers | 🖼️ Images</p><button onclick="document.getElementById('helpModal').classList.remove('show')">OK</button></div></div>
<script>
let prov='<?= $defaultProvider ?>';let hist=[];let files=[];
document.addEventListener('DOMContentLoaded',()=>{const o=document.querySelector('[data-prov="'+prov+'"]');if(o)o.classList.add('active')});
function esc(s){const d=document.createElement('div');d.textContent=s;return d.innerHTML}
function fmt(s){return s.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>').replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank">$1</a>').replace(/\n/g,'<br>')}
function selProv(p,n){prov=p;document.getElementById('currentProvider').textContent=n;document.querySelectorAll('.provider-option').forEach(e=>e.classList.remove('active'));const o=document.querySelector('[data-prov="'+p+'"]');if(o)o.classList.add('active');document.getElementById('providerMenu').classList.remove('show')}
function showHelp(){document.getElementById('helpModal').classList.add('show')}
function newChat(){hist=[];files=[];document.getElementById('msgs').innerHTML='<div class="welcome" id="welcome"><div class="welcome-icon">🧞</div><h2>Bonjour</h2><p>Assistant IA WEVADS</p><div class="quick-actions"><button class="quick-btn" onclick="sendQuick(\'Génère un PDF\')"><i class="fas fa-file-pdf" style="color:#ef4444"></i> PDF</button><button class="quick-btn" onclick="sendQuick(\'Génère un Word\')"><i class="fas fa-file-word" style="color:#2563eb"></i> Word</button><button class="quick-btn" onclick="sendQuick(\'Génère un Excel\')"><i class="fas fa-file-excel" style="color:#16a34a"></i> Excel</button></div></div>';closeArt()}
function sendQuick(m){document.getElementById('input').value=m;send()}
function handleFiles(f){for(let x of f)files.push(x)}
function addMsg(role,txt,meta={}){const w=document.getElementById('welcome');if(w)w.style.display='none';const d=document.createElement('div');d.className='msg msg-'+role;if(role==='user')d.innerHTML='<div class="bubble">'+esc(txt)+'</div>';else{let tags='<span class="tag prov">'+(meta.provider||prov.toUpperCase())+'</span>';if(meta.kb_used)tags+='<span class="tag kb">📚 KB</span>';if(meta.duration)tags+='<span class="tag">'+meta.duration+'ms</span>';d.innerHTML='<div class="avatar">🧞</div><div class="msg-wrap"><div class="msg-content">'+fmt(txt)+'</div><div class="msg-footer">'+tags+'</div></div>'}document.getElementById('msgs').appendChild(d);document.getElementById('msgs').scrollTop=9999}
async function send(){
const inp=document.getElementById('input');const m=inp.value.trim();if(!m)return;inp.value='';
addMsg('user',m);hist.push({role:'user',content:m});
document.getElementById('typing').classList.add('show');
try{
const fd=new FormData();fd.append('message',m);fd.append('provider',prov);fd.append('history',JSON.stringify(hist.slice(-6)));files.forEach(f=>fd.append('files[]',f));
const r=await fetch('/api/widget-api.php',{method:'POST',body:fd});const d=await r.json();
document.getElementById('typing').classList.remove('show');
if(d.success){addMsg('assistant',d.response,{provider:d.provider,duration:d.duration_ms,kb_used:d.kb_used});hist.push({role:'assistant',content:d.response});if(d.artifacts&&d.artifacts.length>0)showArt(d.artifacts[0])}
else addMsg('assistant','❌ '+(d.error||'Erreur'))
}catch(e){document.getElementById('typing').classList.remove('show');addMsg('assistant','❌ '+e.message)}
files=[]
}
function showArt(a){document.getElementById('artTitle').textContent=a.title||'Document';document.getElementById('artDL').href=a.url;const c=document.getElementById('artContent');if(a.type==='pdf')c.innerHTML='<iframe src="'+a.url+'"></iframe>';else if(a.type==='image')c.innerHTML='<div style="display:flex;align-items:center;justify-content:center;height:100%;padding:1rem"><img src="'+a.url+'" style="max-width:100%;max-height:100%"></div>';else c.innerHTML='<div style="text-align:center;padding:3rem"><i class="fas fa-file-alt" style="font-size:4rem;color:#06b6d4"></i><h3 style="margin:1rem 0">'+a.file+'</h3><a href="'+a.url+'" class="btn" download>Télécharger</a></div>';document.getElementById('artPanel').classList.add('open')}
function closeArt(){document.getElementById('artPanel').classList.remove('open')}
document.addEventListener('click',e=>{if(!e.target.closest('.provider-select'))document.getElementById('providerMenu').classList.remove('show');if(e.target.classList.contains('modal'))e.target.classList.remove('show')});
// === TOOLS FUNCTIONS ===
function toggleTools() {
const panel = document.getElementById("toolsPanel");
panel.style.display = panel.style.display === "none" ? "block" : "none";
}
function sendQuick(text) {
document.getElementById("messageInput").value = text;
document.getElementById("messageInput").focus();
}
async function runTool(action, params = {}) {
const url = new URL("/commonia/hamid-tools.php", window.location.origin);
url.searchParams.set("action", action);
for (const [k, v] of Object.entries(params)) {
url.searchParams.set(k, v);
}
try {
addMessage("assistant", `🔧 Exécution de ${action}...`);
const res = await fetch(url);
const data = await res.json();
let resultHTML = `<div class="tool-result"><div class="tool-header">🔧 ${action}</div><pre>${JSON.stringify(data, null, 2)}</pre></div>`;
addMessage("assistant", resultHTML, true);
} catch (e) {
addMessage("assistant", `❌ Erreur: ${e.message}`);
}
}
function promptTool(action, label, param, defaultVal = "") {
const value = prompt(label, defaultVal);
if (value) {
runTool(action, { [param]: value });
}
}
function addMessage(role, content, isHTML = false) {
const container = document.getElementById("messagesContainer") || document.querySelector(".messages-container");
if (!container) return;
const msg = document.createElement("div");
msg.className = "message " + role;
if (isHTML) {
msg.innerHTML = content;
} else {
msg.textContent = content;
}
container.appendChild(msg);
container.scrollTop = container.scrollHeight;
}
</script>
</body></html>
<!-- Tools Panel Modal -->
<div id="toolsPanelModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.8);z-index:9999;padding:2rem;overflow-y:auto">
<div style="max-width:800px;margin:0 auto;background:#1e293b;border-radius:16px;padding:1.5rem;border:1px solid #334155">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem">
<h2 style="color:#06b6d4;margin:0">🔧 Tools Système HAMID</h2>
<button onclick="toggleToolsPanel()" style="background:none;border:none;color:#94a3b8;font-size:1.5rem;cursor:pointer">✕</button>
</div>
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:0.75rem;margin-bottom:1rem">
<button onclick="runTool('status')" class="tool-btn-modal">📊 Status</button>
<button onclick="runTool('tables')" class="tool-btn-modal">🗄️ Tables DB</button>
<button onclick="promptAndRun('list','Chemin:','/opt/wevads/public')" class="tool-btn-modal">📁 Fichiers</button>
<button onclick="promptAndRun('dns','Domaine:')" class="tool-btn-modal">📧 DNS</button>
<button onclick="promptAndRun('bash','Commande:')" class="tool-btn-modal">💻 Bash</button>
<button onclick="promptAndRun('sql','Requête SQL:')" class="tool-btn-modal">🔎 SQL</button>
<button onclick="promptAndRun('read','Chemin fichier:')" class="tool-btn-modal">📄 Lire</button>
<button onclick="promptAndRun('calc','Expression:')" class="tool-btn-modal">🧮 Calcul</button>
</div>
<div id="toolResultArea" style="background:#0f172a;border-radius:8px;padding:1rem;min-height:200px;max-height:400px;overflow-y:auto">
<div style="color:#64748b;text-align:center">Cliquez sur un tool pour l'exécuter</div>
</div>
</div>
</div>
<style>
.tool-btn-modal{display:flex;flex-direction:column;align-items:center;gap:0.25rem;padding:0.75rem;background:linear-gradient(135deg,#0f172a,#1e293b);border:1px solid #334155;border-radius:8px;color:#e2e8f0;cursor:pointer;font-size:0.85rem;transition:all 0.2s}
.tool-btn-modal:hover{border-color:#06b6d4;transform:translateY(-2px);background:linear-gradient(135deg,#1e3a5f,#0f172a)}
</style>
<script>
function toggleToolsPanel(){
const p=document.getElementById('toolsPanelModal');
p.style.display=p.style.display==='none'?'flex':'none';
}
async function runTool(action,params={}){
const area=document.getElementById('toolResultArea');
area.innerHTML='<div style="color:#06b6d4">⏳ Exécution de '+action+'...</div>';
const url=new URL('/commonia/hamid-tools.php',location.origin);
url.searchParams.set('action',action);
for(const[k,v]of Object.entries(params))url.searchParams.set(k,v);
try{
const res=await fetch(url);
const data=await res.json();
area.innerHTML='<div style="color:#06b6d4;font-weight:bold;margin-bottom:0.5rem">🔧 '+action+'</div><pre style="color:#10b981;white-space:pre-wrap;margin:0">'+JSON.stringify(data,null,2)+'</pre>';
}catch(e){
area.innerHTML='<div style="color:#ef4444">❌ Erreur: '+e.message+'</div>';
}
}
function promptAndRun(action,label,defaultVal=''){
const val=prompt(label,defaultVal);
if(val){
const paramMap={list:'path',dns:'domain',bash:'cmd',sql:'sql',read:'path',calc:'expr',search:'q',fetch:'url'};
runTool(action,{[paramMap[action]||'q']:val});
}
}
</script>