/** * Prompt Analyzer — Frontend Logic */ const API_BASE = window.location.origin; let currentAnalysisId = null; let currentResult = null; // ── Character count ─────────────────────────────────────────── const promptInput = document.getElementById('prompt-input'); const charCount = document.getElementById('char-count'); promptInput.addEventListener('input', () => { const len = promptInput.value.length; charCount.textContent = `${len.toLocaleString()} characters`; }); // ── Analyze ─────────────────────────────────────────────────── async function analyzePrompt() { const prompt = promptInput.value.trim(); if (!prompt) { showToast('Please enter a prompt to analyze', 'warning'); return; } const context = document.getElementById('context-input').value.trim() || null; const projectId = document.getElementById('project-input').value.trim() || null; const btn = document.getElementById('analyze-btn'); btn.disabled = true; hideResults(); hideError(); showLoading(); try { const response = await fetch(`${API_BASE}/analyze`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt, context, project_id: projectId, }), }); if (!response.ok) { const err = await response.json().catch(() => ({})); throw new Error(err.detail || `HTTP ${response.status}`); } const result = await response.json(); currentResult = result; currentAnalysisId = result.analysis_id; hideLoading(); renderResults(result); } catch (error) { hideLoading(); showError(error.message); } finally { btn.disabled = false; } } // ── Render Results ──────────────────────────────────────────── function renderResults(result) { const section = document.getElementById('results-section'); section.classList.remove('hidden'); // Overall score const score = result.overall_score; const scoreCard = document.getElementById('overall-score-card'); const scoreRing = document.getElementById('score-ring'); const scoreValue = document.getElementById('overall-score'); const scoreLabel = document.getElementById('overall-label'); // Remove old class scoreCard.className = 'overall-score-card'; if (score >= 85) { scoreCard.classList.add('score-excellent'); scoreLabel.textContent = 'Excellent — This prompt is well-crafted'; } else if (score >= 65) { scoreCard.classList.add('score-good'); scoreLabel.textContent = 'Good — Minor improvements possible'; } else if (score >= 40) { scoreCard.classList.add('score-fair'); scoreLabel.textContent = 'Fair — Several issues to address'; } else { scoreCard.classList.add('score-poor'); scoreLabel.textContent = 'Poor — Major improvements needed'; } // Animate ring const circumference = 2 * Math.PI * 52; // r=52 const offset = circumference - (score / 100) * circumference; scoreRing.style.strokeDashoffset = offset; // Animate number animateNumber(scoreValue, score); // Dimension scores const dimensions = ['clarity', 'token_efficiency', 'goal_alignment', 'structure', 'vagueness_index']; dimensions.forEach(dim => { const data = result.scores[dim]; const numEl = document.querySelector(`[data-dimension="${dim}"]`); const reasoningEl = document.getElementById(`reasoning-${dim}`); animateNumber(numEl, data.score); reasoningEl.textContent = data.reasoning; // Color the score const card = document.getElementById(`score-${dim}`); card.style.borderColor = getScoreColor(data.score); numEl.style.color = getScoreColor(data.score); }); // Mistakes const mistakesList = document.getElementById('mistakes-list'); const mistakeCount = document.getElementById('mistake-count'); const mistakes = result.mistakes || []; mistakeCount.textContent = `${mistakes.length} issue${mistakes.length !== 1 ? 's' : ''}`; mistakeCount.className = mistakes.length === 0 ? 'badge badge-success' : 'badge badge-error'; if (mistakes.length === 0) { mistakesList.innerHTML = `
No issues found — great prompt!