Nessun oggetto della modifica
Nessun oggetto della modifica
 
(9 versioni intermedie di uno stesso utente non sono mostrate)
Riga 63: Riga 63:
         <div class="mpai-composer">
         <div class="mpai-composer">
           <textarea id="mpai-input" rows="3" placeholder="Scrivi qui la tua domanda..."></textarea>
           <textarea id="mpai-input" rows="3" placeholder="Scrivi qui la tua domanda..."></textarea>
           <button id="mpai-send" class="mpai-btn primary">Invia</button>
 
           <div class="mpai-composer-right">
            <label class="mpai-check" style="margin:0 0 6px 0;">
              <input id="mpai-drop-urls" type="checkbox">
              Ignora/Cancella URL e allegati per questo invio
            </label>
            <button id="mpai-send" class="mpai-btn primary">Invia</button>
          </div>
         </div>
         </div>
       </main>
       </main>
Riga 95: Riga 102:
     .mpai-title{font-size:20px;font-weight:700}
     .mpai-title{font-size:20px;font-weight:700}
     .mpai-actions{display:flex;gap:8px}
     .mpai-actions{display:flex;gap:8px}
     .mpai-btn{border:1px solid var(--line);background:var(--card);padding:.45rem .8rem;border-radius:8px;cursor:pointer}
     .mpai-btn{border:1px solid var(--line);background:#fff;padding:.45rem .8rem;border-radius:8px;cursor:pointer}
     .mpai-btn:hover{background:#f3f4f6}
     .mpai-btn:hover{background:#f3f4f6}
     .mpai-btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}
     .mpai-btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}
Riga 102: Riga 109:
     .muted{color:var(--muted)}
     .muted{color:var(--muted)}
     .mpai-grid{display:grid;grid-template-columns:260px minmax(0,1fr) 260px;gap:12px}
     .mpai-grid{display:grid;grid-template-columns:260px minmax(0,1fr) 260px;gap:12px}
     .mpai-col{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:12px}
     .mpai-col{background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px}
     .mpai-left,.mpai-right{max-height:75vh;overflow:auto}
     .mpai-left,.mpai-right{max-height:75vh;overflow:auto}
     .mpai-projects{display:flex;flex-direction:column;gap:6px;margin:8px 0}
     .mpai-projects{display:flex;flex-direction:column;gap:6px;margin:8px 0}
Riga 127: Riga 134:
     .mpai-composer{display:flex;gap:8px;align-items:flex-end}
     .mpai-composer{display:flex;gap:8px;align-items:flex-end}
     .mpai-composer textarea{flex:1 1 auto;min-height:90px;border:1px solid var(--line);border-radius:12px;padding:10px}
     .mpai-composer textarea{flex:1 1 auto;min-height:90px;border:1px solid var(--line);border-radius:12px;padding:10px}
    .mpai-composer-right{display:flex;flex-direction:column;gap:6px}
    /* --- Blocchi codice nelle risposte + copia --- */
    .mp-code{border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;margin:.5rem 0;background:#fff}
    .mp-code__hdr{display:flex;justify-content:space-between;align-items:center;padding:.5rem .75rem;border-bottom:1px solid #e5e7eb;background:#f8fafc}
    .mp-code__lang{font-family:ui-monospace, Menlo, Consolas, monospace;color:#334155}
    .mp-copy{border:1px solid #e5e7eb;background:#fff;border-radius:8px;padding:.25rem .5rem;cursor:pointer}
    .mp-copy:hover{background:#f1f5f9}
    .mp-code pre{margin:0;padding:.75rem 1rem;overflow:auto;font-family:ui-monospace, Menlo, Consolas, monospace;font-size:13px}
     @media (max-width:1100px){.mpai-grid{grid-template-columns:1fr}.mpai-left,.mpai-right{max-height:none}}
     @media (max-width:1100px){.mpai-grid{grid-template-columns:1fr}.mpai-left,.mpai-right{max-height:none}}
   </style>
   </style>


   <!-- ============ JS (tutto qui) ============ -->
   <!-- ========= SEZIONI LEGACY (nascoste) ========= -->
  <script>
  // ======== Invio prompt via proxy sicuro ========
// Definizione funzione + binding dei pulsanti/shortcut
 
async function sendPrompt(){
  const chatEl = document.querySelector('#mpai-chat');
  const ta    = document.querySelector('#mpai-input');
  const model  = (document.querySelector('#mpai-model')?.value || 'gpt-4o-2024-05-13').trim();
  const temp  = parseFloat(document.querySelector('#mpai-temp')?.value || '0.7') || 0.7;
  const sanitizedOnly = !!(document.querySelector('#mpai-sanitized-only')?.checked);
 
  const content = (ta.value || '').trim();
  if (!content){ ta.focus(); return; }
 
  // Se non c'è progetto, usa bozza locale
  if (!window.currentProject && !window.sessionId){
    ensureSession();
    loadSession(window.sessionId);
  }
 
  // Mostra subito il messaggio dell’utente
  history.push({role:'user', content});
  appendMsg('user', content);
  ta.value = '';
 
  // Costruisci prompt preface
  const contextName = window.currentProject
    ? `Progetto: ${window.currentProject}`
    : `Sessione: ${window.sessionMeta?.title || 'Nuova conversazione'}`;
 
  const fileNames = (attachments || []).map(a => a.name).join(', ');
  const preface = `${contextName}
File allegati${sanitizedOnly ? ' (sanificati)' : ''}: ${fileNames || 'nessuno'}
 
Istruzioni: rispondi in ITALIANO, struttura chiara (titoli, punti elenco), sii operativo. Temperatura: ${temp}.
---
Utente:
${content}`;
 
  // Placeholder “Elaboro…”
  const pending = document.createElement('div');
  pending.className = 'mpai-msg';
  pending.innerHTML = '<em class="muted">Elaboro…</em>';
  chatEl.appendChild(pending);
  chatEl.scrollTop = chatEl.scrollHeight;
 
  try{
    const r = await fetch('/dashboard/api/openai_project_gpt.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      cache: 'no-store',
      body: JSON.stringify({ model, prompt: preface })
    });
 
    const raw = await r.text();
 
    // Se la risposta non è 2xx, mostra l’errore “grezzo”
    if (!r.ok){
      pending.remove();
      appendMsg('error', `HTTP ${r.status} ${r.statusText}\n\n${raw || '(nessun body)'}`);
      return;
    }
 
    // Prova a parse-are il JSON
    let j;
    try{ j = JSON.parse(raw); }
    catch(e){
      pending.remove();
      appendMsg('error', `Risposta non in JSON:\n\n${raw.slice(0,1500)}`);
      return;
    }
 
    pending.remove();
 
    if (j.status === 'ok' && j.result){
      // Rinomina la bozza alla prima risposta
      if (!window.currentProject && window.sessionMeta && window.sessionMeta.title === 'Nuova conversazione'){
        window.sessionMeta.title = (content.slice(0,48) || 'Nuova conversazione');
        saveSession && saveSession();
      }
      history.push({role:'assistant', content: j.result});
      appendMsg('assistant', j.result);
      saveLocal && saveLocal();
    } else {
      const err = j.error || 'Errore sconosciuto';
      appendMsg('error', `API error: ${err}\n\nRAW:\n${(j.raw||'').slice(0,1500)}`);
    }
  }catch(e){
    pending.remove();
    appendMsg('error', `Errore di rete/JS: ${e.message}`);
  }
}
 
// Binding: click su “Invia” e ⌘/Ctrl+Invio nell’area di testo
document.addEventListener('click', (e)=>{
  if (e.target && e.target.id === 'mpai-send') sendPrompt();
});
document.addEventListener('keydown', (e)=>{
  if ((e.metaKey||e.ctrlKey) && e.key === 'Enter'){
    const ta = document.querySelector('#mpai-input');
    if (ta && ta === document.activeElement){ e.preventDefault(); sendPrompt(); }
  }
});
 
// opzionale: utile per test da console
window.sendPrompt = sendPrompt;
  </script>
 
  <!-- ========== SEZIONI LEGACY (nascoste) ========== -->
   <div id="api-settings" style="display:none; padding:1rem; border:1px solid #ccc; border-radius:8px; background:#f9f9f9;">
   <div id="api-settings" style="display:none; padding:1rem; border:1px solid #ccc; border-radius:8px; background:#f9f9f9;">
     <strong>Connessione API (protetta dal server)</strong><br><br>
     <strong>Connessione API (protetta dal server)</strong><br><br>
     <label>Modello</label>
     <label>Modello</label>
     <select id="model-select" style="width:100%; margin-bottom:0.5rem;">
     <select id="model-select" style="width:100%; margin-bottom:0.5rem;">
Riga 248: Riga 155:
       <option value="gpt-4-turbo-2024-04-09">gpt-4-turbo-2024-04-09</option>
       <option value="gpt-4-turbo-2024-04-09">gpt-4-turbo-2024-04-09</option>
     </select>
     </select>
     <label>Prompt di test</label>
     <label>Prompt di test</label>
     <textarea id="test-prompt" rows="3" style="width:100%; margin-bottom:0.5rem;">Dimmi una curiosità sulla mandibola</textarea><br>
     <textarea id="test_prompt" rows="3" style="width:100%; margin-bottom:0.5rem;">Dimmi una curiosità sulla mandibola</textarea>
     <button onclick="(async()=>{try{const r=await fetch('/dashboard/api/openai_project_gpt.php',{method:'POST',headers:{'Content-Type':'application/json'},credentials:'include',body:JSON.stringify({model:document.getElementById('model-select').value,prompt:document.getElementById('test-prompt').value})}); const j=await r.json(); document.getElementById('api-result').textContent=JSON.stringify(j,null,2);}catch(e){document.getElementById('api-result').textContent=e.message;}})()">▶️ Esegui</button>
 
     <label style="display:inline-flex; gap:.4rem; align-items:center; margin:.25rem 0 .75rem;">
      <input id="test_drop_urls" type="checkbox">
      Ignora/Cancella URL e allegati per questo invio
    </label><br>
 
    <button id="test_run">Esegui</button>
 
     <pre id="api-result" style="background:#f0f0f0; padding:1rem; border:1px solid #ccc; margin-top:1rem; white-space:pre-wrap;"></pre>
     <pre id="api-result" style="background:#f0f0f0; padding:1rem; border:1px solid #ccc; margin-top:1rem; white-space:pre-wrap;"></pre>
   </div>
   </div>
<script>
// JS minimo temporaneo per sbloccare la pagina
// (serve solo a NON avere errori di sintassi)
</script>
</html>
</html>

Versione attuale delle 15:48, 19 ott 2025

🔧 Dashboard Operativa – Masticationpedia

Centro di comando per progetti, API, file e backup

🧾 Apri Log Dashboard