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> | |