Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>Code Review Assistant Dashboard</title> | |
<link | |
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" | |
rel="stylesheet" | |
/> | |
<link | |
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css" | |
rel="stylesheet" | |
/> | |
<link | |
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css" | |
rel="stylesheet" | |
/> | |
</head> | |
<body class="bg-gray-100"> | |
<div class="min-h-screen"> | |
<!-- Navigation --> | |
<nav class="bg-gray-800 text-white p-4"> | |
<div class="container mx-auto flex justify-between items-center"> | |
<h1 class="text-xl font-bold">Code Review Assistant</h1> | |
<div class="flex space-x-4"> | |
<button | |
id="metricsBtn" | |
class="px-4 py-2 bg-blue-600 rounded hover:bg-blue-700" | |
> | |
Metrics | |
</button> | |
<button | |
id="historyBtn" | |
class="px-4 py-2 bg-green-600 rounded hover:bg-green-700" | |
> | |
History | |
</button> | |
</div> | |
</div> | |
</nav> | |
<!-- Main Content --> | |
<div class="container mx-auto p-6"> | |
<!-- Code Input Section --> | |
<div class="mb-8 bg-white rounded-lg shadow-lg p-6"> | |
<h2 class="text-2xl font-bold mb-4">Submit Code for Review</h2> | |
<div class="mb-4"> | |
<select id="languageSelect" class="w-full p-2 border rounded"> | |
<option value="python">Python</option> | |
<option value="javascript">JavaScript</option> | |
<option value="java">Java</option> | |
<option value="cpp">C++</option> | |
<option value="typescript">TypeScript</option> | |
<option value="go">Go</option> | |
<option value="rust">Rust</option> | |
<option value="other">Other</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<textarea id="codeInput" class="w-full h-64 font-mono"></textarea> | |
</div> | |
<button | |
id="submitBtn" | |
class="px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700" | |
> | |
Submit for Review | |
</button> | |
</div> | |
<!-- Review Results Section --> | |
<div | |
id="reviewResults" | |
class="bg-white rounded-lg shadow-lg p-6 mb-8 hidden" | |
> | |
<h2 class="text-2xl font-bold mb-4">Review Results</h2> | |
<div id="reviewContent" class="space-y-4"> | |
<div id="issues" class="bg-red-50 p-4 rounded-lg"></div> | |
<div id="improvements" class="bg-blue-50 p-4 rounded-lg"></div> | |
<div id="bestPractices" class="bg-green-50 p-4 rounded-lg"></div> | |
<div id="security" class="bg-yellow-50 p-4 rounded-lg"></div> | |
</div> | |
<div id="reviewMetrics" class="mt-4 text-sm text-gray-600"></div> | |
</div> | |
<!-- Metrics Modal --> | |
<div | |
id="metricsModal" | |
class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden" | |
> | |
<div class="bg-white rounded-lg p-6 max-w-2xl mx-auto mt-20"> | |
<h2 class="text-2xl font-bold mb-4">Performance Metrics</h2> | |
<div id="metricsContent" class="space-y-4"></div> | |
<button | |
class="closeModal mt-4 px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700" | |
> | |
Close | |
</button> | |
</div> | |
</div> | |
<!-- History Modal --> | |
<div | |
id="historyModal" | |
class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden" | |
> | |
<div class="bg-white rounded-lg p-6 max-w-4xl mx-auto mt-20"> | |
<h2 class="text-2xl font-bold mb-4">Review History</h2> | |
<div | |
id="historyContent" | |
class="space-y-4 max-h-96 overflow-y-auto" | |
></div> | |
<button | |
class="closeModal mt-4 px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700" | |
> | |
Close | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Scripts --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/python/python.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script> | |
<script> | |
// Initialize CodeMirror | |
const editor = CodeMirror.fromTextArea( | |
document.getElementById("codeInput"), | |
{ | |
lineNumbers: true, | |
mode: "python", | |
theme: "monokai", | |
lineWrapping: true, | |
} | |
); | |
// Language selector | |
document | |
.getElementById("languageSelect") | |
.addEventListener("change", (e) => { | |
editor.setOption("mode", e.target.value); | |
}); | |
// Format review section | |
function formatReviewSection(section) { | |
if (!section || !section.items || section.items.length === 0) return ""; | |
return ` | |
<h3 class="font-bold mb-2">${section.type}</h3> | |
<ul class="list-disc pl-5"> | |
${section.items.map((item) => `<li>${item}</li>`).join("")} | |
</ul> | |
`; | |
} | |
// Submit code for review | |
document | |
.getElementById("submitBtn") | |
.addEventListener("click", async () => { | |
const code = editor.getValue(); | |
const language = document.getElementById("languageSelect").value; | |
try { | |
const response = await fetch("/api/v1/review", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify({ | |
code, | |
language, | |
}), | |
}); | |
const data = await response.json(); | |
// Display review results | |
document.getElementById("reviewResults").classList.remove("hidden"); | |
// Update each section | |
const sections = { | |
issues: "Issues", | |
improvements: "Improvements", | |
bestPractices: "Best Practices", | |
security: "Security" | |
}; | |
// Find and display each section | |
Object.entries(sections).forEach(([id, type]) => { | |
const section = data.suggestions.find(s => s.type === type); | |
document.getElementById(id).innerHTML = formatReviewSection(section) || ""; | |
}); | |
// Display metrics | |
document.getElementById("reviewMetrics").innerHTML = ` | |
<p>Review ID: ${data.review_id}</p> | |
<p>Response Time: ${data.metrics.response_time.toFixed(2)}s</p> | |
<p>Code Length: ${data.metrics.code_length} characters</p> | |
<p>Suggestions: ${data.metrics.suggestion_count}</p> | |
`; | |
} catch (error) { | |
alert("Error submitting code for review: " + error.message); | |
} | |
}); | |
// Metrics button | |
document | |
.getElementById("metricsBtn") | |
.addEventListener("click", async () => { | |
try { | |
const response = await fetch("/api/v1/metrics"); | |
const data = await response.json(); | |
const metricsHtml = ` | |
<div class="grid grid-cols-2 gap-4"> | |
<div class="p-4 bg-gray-100 rounded"> | |
<h3 class="font-bold">Total Reviews</h3> | |
<p>${data.total_reviews}</p> | |
</div> | |
<div class="p-4 bg-gray-100 rounded"> | |
<h3 class="font-bold">Average Response Time</h3> | |
<p>${data.avg_response_time.toFixed(2)}s</p> | |
</div> | |
<div class="p-4 bg-gray-100 rounded"> | |
<h3 class="font-bold">Average Suggestions</h3> | |
<p>${data.avg_suggestions.toFixed(1)}</p> | |
</div> | |
<div class="p-4 bg-gray-100 rounded"> | |
<h3 class="font-bold">Reviews Today</h3> | |
<p>${data.reviews_today}</p> | |
</div> | |
</div> | |
`; | |
document.getElementById("metricsContent").innerHTML = metricsHtml; | |
document.getElementById("metricsModal").classList.remove("hidden"); | |
} catch (error) { | |
alert("Error fetching metrics: " + error.message); | |
} | |
}); | |
// History button | |
document | |
.getElementById("historyBtn") | |
.addEventListener("click", async () => { | |
try { | |
const response = await fetch("/api/v1/history"); | |
const data = await response.json(); | |
const historyHtml = data | |
.map( | |
(entry) => ` | |
<div class="border-b pb-4"> | |
<div class="flex justify-between items-center mb-2"> | |
<span class="font-bold">${new Date( | |
entry.timestamp | |
).toLocaleString()}</span> | |
<span class="text-sm text-gray-600"> | |
Language: ${entry.language} | | |
Response Time: ${entry.metrics.response_time.toFixed(2)}s | |
</span> | |
</div> | |
<div class="space-y-2"> | |
${entry.suggestions | |
.map((section) => formatReviewSection(section)) | |
.join("")} | |
</div> | |
</div> | |
` | |
) | |
.join(""); | |
document.getElementById("historyContent").innerHTML = historyHtml; | |
document.getElementById("historyModal").classList.remove("hidden"); | |
} catch (error) { | |
alert("Error fetching history: " + error.message); | |
} | |
}); | |
// Close modals | |
document.querySelectorAll(".closeModal").forEach((button) => { | |
button.addEventListener("click", () => { | |
document.getElementById("metricsModal").classList.add("hidden"); | |
document.getElementById("historyModal").classList.add("hidden"); | |
}); | |
}); | |
</script> | |
</body> | |
</html> | |