|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Cursor AI Interaction Tracker - Demo</title> |
|
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<script> |
|
tailwind.config = { |
|
darkMode: 'class', |
|
theme: { |
|
extend: { |
|
colors: { |
|
primary: { |
|
"50": "#f5f3ff", |
|
"100": "#ede9fe", |
|
"200": "#ddd6fe", |
|
"300": "#c4b5fd", |
|
"400": "#a78bfa", |
|
"500": "#8b5cf6", |
|
"600": "#7c3aed", |
|
"700": "#6d28d9", |
|
"800": "#5b21b6", |
|
"900": "#4c1d95", |
|
"950": "#320e5e" |
|
}, |
|
secondary: { |
|
"50": "#f0fdf4", |
|
"100": "#dcfce7", |
|
"200": "#bbf7d0", |
|
"300": "#86efac", |
|
"400": "#4ade80", |
|
"500": "#22c55e", |
|
"600": "#16a34a", |
|
"700": "#15803d", |
|
"800": "#166534", |
|
"900": "#14532d", |
|
"950": "#072711" |
|
}, |
|
reddish: { |
|
"50": "#fef2f2", |
|
"100": "#fee2e2", |
|
"200": "#fecaca", |
|
"300": "#fca5a5", |
|
"400": "#f87171", |
|
"500": "#ef4444", |
|
"600": "#dc2626", |
|
"700": "#b91c1c", |
|
"800": "#991b1b", |
|
"900": "#7f1d1d", |
|
"950": "#450808" |
|
} |
|
} |
|
}, |
|
fontFamily: { |
|
'body': [ |
|
'Inter', |
|
'ui-sans-serif', |
|
'system-ui', |
|
'-apple-system', |
|
'system-ui', |
|
'Segoe UI', |
|
'Roboto', |
|
'Helvetica Neue', |
|
'Arial', |
|
'Noto Sans', |
|
'sans-serif', |
|
'Apple Color Emoji', |
|
'Segoe UI Emoji', |
|
'Segoe UI Symbol', |
|
'Noto Color Emoji' |
|
], |
|
'sans': [ |
|
'Inter', |
|
'ui-sans-serif', |
|
'system-ui', |
|
'-apple-system', |
|
'system-ui', |
|
'Segoe UI', |
|
'Roboto', |
|
'Helvetica Neue', |
|
'Arial', |
|
'Noto Sans', |
|
'sans-serif', |
|
'Apple Color Emoji', |
|
'Segoe UI Emoji', |
|
'Segoe UI Symbol', |
|
'Noto Color Emoji' |
|
] |
|
} |
|
} |
|
} |
|
</script> |
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.css" rel="stylesheet" /> |
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
<style> |
|
|
|
.code-block { |
|
padding: 12px; |
|
background-color: #f3f4f6; |
|
border-radius: 6px; |
|
overflow-x: auto; |
|
font-family: 'Courier New', Courier, monospace; |
|
color: #1e293b; |
|
margin-top: 6px; |
|
margin-bottom: 6px; |
|
border: 1px solid #ddd; |
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05); |
|
} |
|
.dark .code-block { |
|
background-color: #1f2937; |
|
color: #f9fafb; |
|
border-color: #444; |
|
} |
|
|
|
.card { |
|
transition: all 0.2s ease-in-out; |
|
} |
|
.card:hover { |
|
transform: translateY(-3px); |
|
box-shadow: 0 6px 12px -2px rgba(50,50,93,0.25), 0 3px 7px -3px rgba(0,0,0,0.3); |
|
} |
|
.card-expand-icon { |
|
transition: transform 0.3s ease-in-out; |
|
} |
|
.card.expanded .card-expand-icon { |
|
transform: rotate(180deg); |
|
} |
|
|
|
.chart-tooltip { |
|
background: rgba(0, 0, 0, 0.8); |
|
color: white; |
|
padding: 5px 10px; |
|
border-radius: 4px; |
|
font-size: 13px; |
|
} |
|
.chart-tooltip-title { |
|
font-weight: bold; |
|
} |
|
.radial-progress { |
|
display: inline-flex; |
|
position: relative; |
|
width: 80px; |
|
height: 80px; |
|
} |
|
.radial-progress svg { |
|
width: 100%; |
|
height: 100%; |
|
} |
|
.radial-progress circle { |
|
cx: 40; |
|
cy: 40; |
|
r: 34; |
|
fill: none; |
|
stroke-width: 6; |
|
stroke-dasharray: 213.63; |
|
transform: rotate(-90deg); |
|
transform-origin: 50% 50%; |
|
transition: stroke-dashoffset 0.5s ease; |
|
} |
|
.radial-progress .bg-circle { |
|
stroke: #e5e7eb; |
|
} |
|
.radial-progress .progress-circle { |
|
stroke: #4ade80; |
|
stroke-dashoffset: 213.63; |
|
} |
|
.radial-progress .progress-value { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
font-size: 16px; |
|
color: #374151; |
|
font-weight: 500; |
|
} |
|
.dark .radial-progress .progress-value { |
|
color: #d1d5db; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body class="bg-gray-50 dark:bg-gray-900"> |
|
|
|
<div class="container mx-auto p-6"> |
|
|
|
|
|
<header class="mb-8"> |
|
<h1 class="text-3xl font-bold text-primary-600 dark:text-primary-400">Cursor AI Interaction Tracker</h1> |
|
<p class="text-gray-700 dark:text-gray-300 mt-2">Visualizing AI-Programmer Collaboration & Improvement</p> |
|
</header> |
|
|
|
|
|
<div class="mb-4"> |
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="interactionTabs" data-tabs-toggle="#interactionTabContent" role="tablist"> |
|
<li class="mr-2" role="presentation"> |
|
<button class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:border-primary-300 hover:text-primary-600 dark:hover:text-primary-300" id="dashboard-tab" data-tabs-target="#dashboard" type="button" role="tab" aria-controls="dashboard" aria-selected="false">Dashboard</button> |
|
</li> |
|
<li class="mr-2" role="presentation"> |
|
<button class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:border-primary-300 hover:text-primary-600 dark:hover:text-primary-300" id="conversations-tab" data-tabs-target="#conversations" type="button" role="tab" aria-controls="conversations" aria-selected="false">Conversations</button> |
|
</li> |
|
<li class="mr-2" role="presentation"> |
|
<button class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:border-primary-300 hover:text-primary-600 dark:hover:text-primary-300" id="precision-tab" data-tabs-target="#precision" type="button" role="tab" aria-controls="precision" aria-selected="false">AI Precision</button> |
|
</li> |
|
<li role="presentation"> |
|
<button class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:border-primary-300 hover:text-primary-600 dark:hover:text-primary-300" id="rules-tab" data-tabs-target="#rules" type="button" role="tab" aria-controls="rules" aria-selected="false">Rules & Feedback</button> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
|
|
<div id="interactionTabContent"> |
|
|
|
|
|
<div class="hidden p-6 rounded-lg bg-gray-100 dark:bg-gray-800" id="dashboard" role="tabpanel" aria-labelledby="dashboard-tab"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
<div class="h-[400px]"> |
|
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Overall AI Accuracy Trend</h2> |
|
<div class="relative h-[350px]"> |
|
<canvas id="accuracyChart"></canvas> |
|
</div> |
|
</div> |
|
<div class="space-y-6"> |
|
<div class="p-6 bg-white rounded-lg shadow-md dark:bg-gray-700"> |
|
<h2 class="mb-4 text-xl font-semibold text-gray-900 dark:text-white">Key Metrics</h2> |
|
<div class="grid grid-cols-2 gap-6"> |
|
<div> |
|
<dl> |
|
<div class="mb-4"> |
|
<dt class="text-gray-500 dark:text-gray-400">Total Interactions</dt> |
|
<dd id="totalInteractionsDash" class="text-2xl font-bold text-primary-600 dark:text-primary-400 mt-1"></dd> |
|
</div> |
|
<div> |
|
<dt class="text-gray-500 dark:text-gray-400">Avg. Precision</dt> |
|
<div class="radial-progress mt-1" id="avgPrecisionRadial"> |
|
<svg> |
|
<circle class="bg-circle" /> |
|
<circle class="progress-circle" /> |
|
</svg> |
|
<span class="progress-value" id="avgPrecisionValueDash"></span> |
|
</div> |
|
</div> |
|
</dl> |
|
</div> |
|
<div> |
|
<dl> |
|
<div class="mb-4"> |
|
<dt class="text-gray-500 dark:text-gray-400">Below 60% Precision</dt> |
|
<dd id="lowPrecisionInteractionsDash" class="text-2xl font-bold text-reddish-600 dark:text-reddish-400 mt-1"></dd> |
|
</div> |
|
</dl> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="p-6 bg-white rounded-lg shadow-md dark:bg-gray-700"> |
|
<h2 class="mb-4 text-xl font-semibold text-gray-900 dark:text-white">Recent Rule Improvements</h2> |
|
<ul id="recentRuleImprovementsDash" class="list-disc list-inside space-y-3 text-gray-700 dark:text-gray-300"> |
|
</ul> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="hidden p-6 rounded-lg bg-gray-100 dark:bg-gray-800" id="conversations" role="tabpanel" aria-labelledby="conversations-tab"> |
|
<div class="mb-6"> |
|
<label for="filterTags" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Filter by Tag:</label> |
|
<select id="filterTags" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"> |
|
<option value="">All Tags</option> |
|
<option value="debugging">Debugging</option> |
|
<option value="api design">API Design</option> |
|
<option value="refactoring">Refactoring</option> |
|
<option value="optimization">Optimization</option> |
|
<option value="algorithm">Algorithm</option> |
|
<option value="deployment">Deployment</option> |
|
<option value="testing">Testing</option> |
|
<option value="angular">Angular</option> |
|
<option value="react">React</option> |
|
<option value="node.js">Node.js</option> |
|
<option value="python">Python</option> |
|
<option value="sql">SQL</option> |
|
<option value="java">Java</option> |
|
</select> |
|
</div> |
|
<div id="conversationList" class="space-y-6"> |
|
|
|
</div> |
|
</div> |
|
|
|
|
|
<div class="hidden p-6 rounded-lg bg-gray-100 dark:bg-gray-800" id="precision" role="tabpanel" aria-labelledby="precision-tab"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
<div class="h-[400px]"> |
|
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Precision Score Distribution</h2> |
|
<div class="relative h-[350px]"> |
|
<canvas id="precisionChart"></canvas> |
|
</div> |
|
</div> |
|
<div class="p-6 bg-white rounded-lg shadow-md dark:bg-gray-700"> |
|
<h2 class="mb-4 text-xl font-semibold text-gray-900 dark:text-white">Precision Breakdown</h2> |
|
<div id="precisionMetrics" class="space-y-4"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="hidden p-6 rounded-lg bg-gray-100 dark:bg-gray-800" id="rules" role="tabpanel" aria-labelledby="rules-tab"> |
|
<h2 class="text-xl font-semibold mb-6 text-gray-900 dark:text-white">AI Rule Improvement Suggestions</h2> |
|
<div id="ruleImprovements" class="space-y-6"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
|
|
</div> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.js"></script> |
|
<script> |
|
// Dummy Data (More Rich & Varied) |
|
const interactions = [ |
|
{ |
|
programmer: "Alice", |
|
date: "2023-12-28", |
|
request: "Fix this Python function that's raising an error", |
|
aiResponse: "```python\ndef process_data(data):\n # Corrected loop condition and index error\n results = []\n for i in range(len(data)):\n if data[i] > 5:\n results.append(data[i] * 2)\n return results\n```", |
|
finalCode: "```python\ndef process_data(data):\n results = []\n for item in data:\n if item > 5:\n results.append(item * 2)\n return results\n```", |
|
precision: 90, |
|
tags: ["debugging", "python", "error handling"], |
|
ruleChange: null, |
|
}, |
|
{ |
|
programmer: "Bob", |
|
date: "2023-12-29", |
|
request: "Suggest a more efficient way to fetch user data in this Node.js API", |
|
aiResponse: "```javascript\n// Using async/await and optimized database query\napp.get('/users', async (req, res) => {\n try {\n const users = await db.query('SELECT id, username, email FROM users WHERE active = true');\n res.json(users);\n } catch (error) {\n res.status(500).send('Server error');\n }\n});\n```", |
|
finalCode: "```javascript\napp.get('/users', async (req, res) => {\n try {\n const users = await db.query('SELECT id, username, email FROM users WHERE active = true ORDER BY username');\n res.json(users);\n } catch (error) {\n res.status(500).send('Server error');\n }\n});\n```", |
|
precision: 75, |
|
tags: ["api design", "node.js", "optimization", "performance"], |
|
ruleChange: { |
|
original: "Suggest improvements for code efficiency", |
|
updated: "Suggest improvements focusing on database query optimization and API response times", |
|
status: "approved", |
|
}, |
|
}, |
|
{ |
|
programmer: "Alice", |
|
date: "2023-12-30", |
|
request: "Refactor this React component to use functional components and hooks", |
|
aiResponse: "```jsx\nimport React, { useState } from 'react';\n\nfunction UserProfile(props) {\n const [isActive, setIsActive] = useState(false);\n\n return (\n <div>\n <h3>{props.name}</h3>\n <button onClick={() => setIsActive(!isActive)}>{isActive ? 'Deactivate' : 'Activate'}</button>\n </div>\n );\n}\n```", |
|
finalCode: "```jsx\nimport React, { useState, useEffect } from 'react';\n\nfunction UserProfile(props) {\n const [isActive, setIsActive] = useState(false);\n const [message, setMessage] = useState('');\n\n useEffect(() => {\n setMessage(isActive ? 'Active User' : 'Inactive User');\n }, [isActive]);\n\n return (\n <div>\n <h3>{props.name} - {message}</h3>\n <button onClick={() => setIsActive(!isActive)}>{isActive ? 'Deactivate' : 'Activate'}</button>\n </div>\n );\n}\n```", |
|
precision: 65, |
|
tags: ["refactoring", "react", "hooks", "component design"], |
|
ruleChange: null, |
|
}, |
|
{ |
|
programmer: "Charlie", |
|
date: "2023-12-31", |
|
request: "Optimize this SQL query to improve retrieval speed", |
|
aiResponse: "```sql\nSELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';\n```", |
|
finalCode: "```sql\nSELECT order_id, customer_id, order_date, total_amount FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31' AND status = 'COMPLETED' ORDER BY order_date DESC LIMIT 100;\n```", |
|
precision: 50, |
|
tags: ["optimization", "sql", "database"], |
|
ruleChange: { |
|
original: "Suggest SQL query optimizations", |
|
updated: "Suggest SQL optimizations considering indexing, specific column selection, and common use cases like pagination and filtering", |
|
status: "pending", |
|
}, |
|
}, |
|
{ |
|
programmer: "Bob", |
|
date: "2024-01-01", |
|
request: "Write a Python function to calculate Fibonacci sequence recursively", |
|
aiResponse: "```python\ndef fibonacci_recursive(n):\n if n <= 1:\n return n\n else:\n return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)\n```", |
|
finalCode: "```python\ndef fibonacci_recursive(n):\n if n <= 1:\n return n\n else:\n return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)\n```", |
|
precision: 100, |
|
tags: ["algorithm", "python", "recursion"], |
|
ruleChange: null |
|
}, |
|
{ |
|
programmer: "Alice", |
|
date: "2024-01-02", |
|
request: "Guide me on deploying a Dockerized app to AWS ECS with CI/CD", |
|
aiResponse: "To deploy to AWS ECS with CI/CD, you can use AWS CodePipeline and CodeBuild. Here's a high-level process...", |
|
finalCode: null, // Conceptual request, no final code |
|
precision: 80, |
|
tags: ["deployment", "docker", "aws", "ecs", "ci/cd"], |
|
ruleChange: null |
|
}, |
|
{ |
|
programmer: "David", |
|
date: "2024-01-03", |
|
request: "Explain Dependency Injection in Angular with a practical example", |
|
aiResponse: "Dependency Injection (DI) in Angular is a design pattern... Here's a simple example using services...", |
|
finalCode: null, // Conceptual request, no final code |
|
precision: 92, |
|
tags: ["angular", "dependency injection", "design patterns"], |
|
ruleChange: null |
|
}, |
|
{ |
|
programmer: "Eve", |
|
date: "2024-01-04", |
|
request: "Write Jest unit tests for this JavaScript utility function", |
|
aiResponse: "```javascript\ndescribe('utilityFunction', () => {\n it('should return correct value for valid input', () => {\n expect(utilityFunction(5)).toBeDefined();\n });\n});\n```", |
|
finalCode: "```javascript\ndescribe('utilityFunction', () => {\n it('should return correct value for valid input', () => {\n expect(utilityFunction(5)).toBe(10); // Example: Assuming function doubles input\n });\n\n it('should handle edge cases like zero or null input', () => {\n expect(utilityFunction(0)).toBe(0);\n expect(utilityFunction(null)).toBe(0);\n });\n});\n```", |
|
precision: 70, |
|
tags: ["testing", "jest", "unit tests"], |
|
ruleChange: { |
|
original: "Provide basic unit test examples", |
|
updated: "Provide comprehensive unit test examples including standard cases, edge cases, and boundary conditions", |
|
status: "approved", |
|
}, |
|
}, |
|
{ |
|
programmer: "Frank", |
|
date: "2024-01-05", |
|
request: "How to optimize performance of a large React application", |
|
aiResponse: "To optimize a large React app, consider techniques like code splitting, memoization, virtualization of lists, and efficient state management...", |
|
finalCode: null, // Conceptual request, no final code |
|
precision: 85, |
|
tags: ["performance", "react", "optimization", "front-end"], |
|
ruleChange: null |
|
}, |
|
{ |
|
programmer: "Grace", |
|
date: "2024-01-06", |
|
request: "Implement a binary search algorithm in Java for sorted array", |
|
aiResponse: "```java\npublic int binarySearch(int[] arr, int target) {\n int low = 0;\n int high = arr.length - 1;\n\n while (low <= high) {\n int mid = low + (high - low) / 2;\n if (arr[mid] == target) return mid;\n if (arr[mid] < target) low = mid + 1;\n else high = mid - 1;\n }\n return -1; // Not found\n}\n```", |
|
finalCode: "```java\npublic int binarySearch(int[] arr, int target) {\n int low = 0;\n int high = arr.length - 1;\n\n while (low <= high) {\n int mid = low + (high - low) / 2;\n if (arr[mid] == target) return mid;\n if (arr[mid] < target) low = mid + 1;\n else high = mid - 1;\n }\n return -1; // Target not found\n}\n```", |
|
precision: 98, |
|
tags: ["algorithm", "java", "binary search", "data structures"], |
|
ruleChange: null |
|
} |
|
]; |
|
|
|
// --- Dashboard Charts and Metrics --- |
|
function initializeDashboard() { |
|
// Metrics Calculation |
|
const totalInteractionsCount = interactions.length; |
|
const avgPrecisionValue = (interactions.reduce((sum, interaction) => sum + interaction.precision, 0) / totalInteractionsCount).toFixed(2); |
|
const lowPrecisionCount = interactions.filter(interaction => interaction.precision < 60).length; |
|
|
|
document.getElementById('totalInteractionsDash').textContent = totalInteractionsCount; |
|
document.getElementById('avgPrecisionValueDash').textContent = `${avgPrecisionValue}%`; |
|
document.getElementById('lowPrecisionInteractionsDash').textContent = lowPrecisionCount; |
|
|
|
// Update the radial progress for average precision |
|
const avgPrecisionRadial = document.getElementById('avgPrecisionRadial'); |
|
const progressCircle = avgPrecisionRadial.querySelector('.progress-circle'); |
|
const circumference = 213.63; |
|
const offset = circumference - (avgPrecisionValue / 100) * circumference; |
|
progressCircle.style.strokeDashoffset = offset; |
|
// Update color based on precision value |
|
progressCircle.style.stroke = avgPrecisionValue >= 70 ? '#4ade80' : avgPrecisionValue >= 60 ? '#facc15' : '#ef4444'; |
|
|
|
// Recent Rule Improvements on Dashboard |
|
const recentRuleImprovementsList = document.getElementById('recentRuleImprovementsDash'); |
|
recentRuleImprovementsList.innerHTML = ''; |
|
interactions.filter(interaction => interaction.ruleChange && interaction.ruleChange.status === 'approved') |
|
.slice(-3) // Take the last 3 |
|
.forEach(interaction => { |
|
const listItem = document.createElement('li'); |
|
listItem.innerHTML = `<span class="font-medium">${interaction.ruleChange.original}</span> <svg class="w-3 h-3 inline-block mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"> |
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/></svg> <span class="font-medium">${interaction.ruleChange.updated}</span>`; |
|
recentRuleImprovementsList.appendChild(listItem); |
|
}); |
|
|
|
// Accuracy Chart |
|
const accuracyData = interactions.map(interaction => interaction.precision); |
|
const accuracyLabels = interactions.map(interaction => interaction.date); |
|
|
|
const accuracyChartRef = document.getElementById('accuracyChart'); |
|
if (window.accuracyChartInstance) { |
|
window.accuracyChartInstance.destroy(); |
|
} |
|
|
|
const chartOptions = { |
|
responsive: true, |
|
maintainAspectRatio: true, |
|
scales: { |
|
y: { |
|
beginAtZero: true, |
|
max: 100, |
|
grid: { |
|
color: 'rgba(0, 0, 0, 0.1)', |
|
borderColor: 'transparent' |
|
}, |
|
ticks: { |
|
font: { |
|
size: 14, |
|
} |
|
} |
|
}, |
|
x: { |
|
grid: { |
|
display: false |
|
}, |
|
ticks: { |
|
font: { |
|
size: 12, |
|
} |
|
} |
|
} |
|
}, |
|
plugins: { |
|
legend: { |
|
display: false |
|
}, |
|
tooltip: { |
|
enabled: true, |
|
backgroundColor: 'rgba(0, 0, 0, 0.8)', |
|
titleFont: { |
|
size: 16, |
|
weight: 'bold' |
|
}, |
|
bodyFont: { |
|
size: 14 |
|
}, |
|
padding: 10, |
|
titleColor: '#ffffff', |
|
bodyColor: '#ffffff', |
|
borderColor: 'rgba(0, 0, 0, 0.2)', |
|
borderWidth: 1, |
|
cornerRadius: 6 |
|
} |
|
} |
|
}; |
|
|
|
window.accuracyChartInstance = new Chart(accuracyChartRef, { |
|
type: 'line', |
|
data: { |
|
labels: accuracyLabels, |
|
datasets: [{ |
|
label: 'AI Accuracy (%)', |
|
data: accuracyData, |
|
borderColor: '#8b5cf6', |
|
backgroundColor: 'rgba(139, 92, 246, 0.2)', |
|
tension: 0.4, |
|
pointRadius: 4, |
|
pointBackgroundColor: '#8b5cf6' |
|
}] |
|
}, |
|
options: { |
|
...chartOptions, |
|
} |
|
}); |
|
|
|
// Add Performance Optimization Section |
|
const performanceOptimization = document.createElement('div'); |
|
performanceOptimization.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
performanceOptimization.innerHTML = ` |
|
<div class="flex items-center justify-between mb-6"> |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Performance Optimization</h3> |
|
<span class="px-3 py-1 text-sm font-medium rounded-full bg-green-100 text-green-800"> |
|
Optimized |
|
</span> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Resource Usage</h4> |
|
<div class="space-y-4"> |
|
<div> |
|
<div class="flex justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">CPU Usage</span> |
|
<span class="text-sm font-medium text-green-600">28%</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"> |
|
<div class="bg-green-600 h-2.5 rounded-full" style="width: 28%"></div> |
|
</div> |
|
</div> |
|
<div> |
|
<div class="flex justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Memory Usage</span> |
|
<span class="text-sm font-medium text-green-600">45%</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"> |
|
<div class="bg-green-600 h-2.5 rounded-full" style="width: 45%"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Load Times</h4> |
|
<div class="space-y-4"> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Average Response</span> |
|
<span class="text-sm font-medium text-green-600">124ms</span> |
|
</div> |
|
<div class="mt-2 text-xs text-gray-500">15% faster than last week</div> |
|
</div> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Peak Response</span> |
|
<span class="text-sm font-medium text-green-600">312ms</span> |
|
</div> |
|
<div class="mt-2 text-xs text-gray-500">8% improvement</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('dashboard').appendChild(performanceOptimization); |
|
|
|
// Add Knowledge Base Section |
|
const knowledgeBase = document.createElement('div'); |
|
knowledgeBase.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
knowledgeBase.innerHTML = ` |
|
<div class="flex items-center justify-between mb-6"> |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Knowledge Base</h3> |
|
<button class="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"> |
|
View All |
|
</button> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6"> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center mb-3"> |
|
<svg class="w-6 h-6 text-primary-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/> |
|
</svg> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white">Best Practices</h4> |
|
</div> |
|
<ul class="space-y-2"> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Code Organization</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Error Handling</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Performance Tips</li> |
|
</ul> |
|
</div> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center mb-3"> |
|
<svg class="w-6 h-6 text-primary-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path d="M9 4.804A7.968 7.968 0 005.5 4c-1.255 0-2.443.29-3.5.804v10A7.969 7.969 0 015.5 14c1.669 0 3.218.51 4.5 1.385A7.962 7.962 0 0114.5 14c1.255 0 2.443.29 3.5.804v-10A7.968 7.968 0 0014.5 4c-1.255 0-2.443.29-3.5.804V12a1 1 0 11-2 0V4.804z"/> |
|
</svg> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white">Learning Resources</h4> |
|
</div> |
|
<ul class="space-y-2"> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Documentation</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Video Tutorials</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Code Examples</li> |
|
</ul> |
|
</div> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center mb-3"> |
|
<svg class="w-6 h-6 text-primary-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/> |
|
</svg> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white">Code Patterns</h4> |
|
</div> |
|
<ul class="space-y-2"> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Design Patterns</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Common Solutions</li> |
|
<li class="text-sm text-gray-700 dark:text-gray-300">• Best Practices</li> |
|
</ul> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('dashboard').appendChild(knowledgeBase); |
|
} |
|
|
|
// --- Conversations View --- |
|
function createConversationCard(interaction, index) { |
|
const card = document.createElement('div'); |
|
card.classList.add( |
|
'card', |
|
'mb-6', |
|
'p-6', |
|
'bg-white', |
|
'border', |
|
'border-gray-200', |
|
'rounded-lg', |
|
'shadow-md', |
|
'dark:bg-gray-700', |
|
'dark:border-gray-600', |
|
'transform', |
|
'transition-all', |
|
'duration-300', |
|
'hover:scale-[1.02]' |
|
); |
|
card.innerHTML = ` |
|
<div class="flex justify-between items-start"> |
|
<div> |
|
<h5 class="text-xl font-bold leading-none text-primary-600 dark:text-primary-400">${interaction.programmer}</h5> |
|
<p class="mb-1 text-sm text-gray-500 dark:text-gray-400">${interaction.date} - Tags: ${interaction.tags.join(', ')}</p> |
|
<p class="font-normal text-gray-700 dark:text-gray-300">Request: ${interaction.request.substring(0, 80)}...</p> |
|
</div> |
|
<span class="bg-${interaction.precision >= 70 ? 'green' : interaction.precision >= 60 ? 'yellow' : 'red'}-100 text-${interaction.precision >= 70 ? 'green' : interaction.precision >= 60 ? 'yellow' : 'red'}-800 text-xs font-medium inline-flex items-center px-2.5 py-0.5 rounded-full dark:bg-${interaction.precision >= 70 ? 'green' : interaction.precision >= 60 ? 'yellow' : 'red'}-900 dark:text-${interaction.precision >= 70 ? 'green' : interaction.precision >= 60 ? 'yellow' : 'red'}-300"> |
|
<svg class="w-3 h-3 mr-1.5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm4.28 14.22a.75.75 0 000-1.06l-4.25-4.25-2.25 2.25a.75.75 0 001.06 1.06l1.69-1.69 3.72 3.72a.75.75 0 001.06 0z"/></svg> |
|
Precision: ${interaction.precision}% |
|
</span> |
|
</div> |
|
<div class="mt-4 hidden transition-all duration-300 ease-in-out" id="details-${index}"> |
|
<p class="font-semibold text-gray-900 dark:text-white">Full Request:</p> |
|
<p class="text-gray-700 dark:text-gray-300">${interaction.request}</p> |
|
|
|
<p class="mt-4 font-semibold text-gray-900 dark:text-white">AI Response:</p> |
|
<div class="code-block"><pre><code class="language-python">${interaction.aiResponse}</code></pre></div> |
|
|
|
${interaction.finalCode ? ` |
|
<p class="mt-4 font-semibold text-gray-900 dark:text-white">Final Implemented Code:</p> |
|
<div class="code-block"><pre><code class="language-python">${interaction.finalCode}</code></pre></div> |
|
` : ''} |
|
|
|
${interaction.ruleChange ? ` |
|
<div class="mt-6 p-4 bg-gray-50 rounded-lg dark:bg-gray-600"> |
|
<h6 class="font-semibold text-gray-900 dark:text-white">Rule Change Suggestion:</h6> |
|
<p class="text-gray-700 dark:text-gray-300"><span class="font-medium">Original:</span> ${interaction.ruleChange.original}</p> |
|
<p class="text-gray-700 dark:text-gray-300"><span class="font-medium">Proposed:</span> ${interaction.ruleChange.updated}</p> |
|
<p class="text-gray-700 dark:text-gray-300">Status: <span class="font-medium">${interaction.ruleChange.status}</span></p> |
|
${interaction.ruleChange.status === 'pending' ? ` |
|
<div class="mt-4 flex space-x-4"> |
|
<button onclick="approveRuleChange(${index})" type="button" class="text-white bg-secondary-700 hover:bg-secondary-800 focus:ring-4 focus:outline-none focus:ring-secondary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-secondary-600 dark:hover:bg-secondary-700 dark:focus:ring-secondary-800">Approve</button> |
|
<button onclick="rejectRuleChange(${index})" type="button" class="text-white bg-reddish-700 hover:bg-reddish-800 focus:ring-4 focus:outline-none focus:ring-reddish-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-reddish-600 dark:hover:bg-reddish-700 dark:focus:ring-reddish-800">Reject</button> |
|
</div> |
|
` : ''} |
|
</div> |
|
` : ''} |
|
</div> |
|
<div class="mt-4 flex justify-end"> |
|
<button data-index="${index}" onclick="toggleConversationDetails(this)" type="button" class="text-primary-600 hover:underline dark:text-primary-500 flex items-center"> |
|
<span id="icon-${index}" class="card-expand-icon"> |
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg> |
|
</span> |
|
<span class="ml-1">Show Details</span> |
|
</button> |
|
</div> |
|
|
|
|
|
<div class="mt-4 bg-gray-50 dark:bg-gray-800 rounded-lg p-4"> |
|
<div class="flex items-center justify-between mb-2"> |
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Response Analysis</h3> |
|
<div class="relative" id="analysis-progress-${index}"> |
|
<svg class="w-8 h-8" viewBox="0 0 36 36"> |
|
<circle cx="18" cy="18" r="16" fill="none" class="stroke-current text-gray-200 dark:text-gray-700" stroke-width="2"></circle> |
|
<circle cx="18" cy="18" r="16" fill="none" class="stroke-current text-primary-500" stroke-width="2" stroke-dasharray="100" stroke-dashoffset="${100 - interaction.precision}" transform="rotate(-90 18 18)"></circle> |
|
</svg> |
|
<span class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm font-medium">${interaction.precision}%</span> |
|
</div> |
|
</div> |
|
<div class="space-y-2"> |
|
<div class="flex items-center"> |
|
<span class="w-3 h-3 rounded-full ${interaction.precision >= 80 ? 'bg-green-500' : interaction.precision >= 60 ? 'bg-yellow-500' : 'bg-red-500'}"></span> |
|
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">Code Quality Score</span> |
|
</div> |
|
<div class="flex items-center"> |
|
<span class="w-3 h-3 rounded-full ${interaction.tags.includes('optimization') ? 'bg-primary-500' : 'bg-gray-300'}"></span> |
|
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">Performance Optimized</span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="mt-4 flex flex-wrap gap-2"> |
|
${interaction.tags.map(tag => ` |
|
<span class="px-3 py-1 text-sm font-medium rounded-full bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-300"> |
|
${tag} |
|
</span> |
|
`).join('')} |
|
</div> |
|
`; |
|
return card; |
|
} |
|
|
|
function renderConversations(filteredInteractions = interactions) { |
|
const conversationListDiv = document.getElementById('conversationList'); |
|
conversationListDiv.innerHTML = ''; |
|
filteredInteractions.forEach((interaction, index) => { |
|
conversationListDiv.appendChild(createConversationCard(interaction, index)); |
|
}); |
|
} |
|
|
|
function toggleConversationDetails(button) { |
|
const index = button.dataset.index; |
|
const detailsDiv = document.getElementById(`details-${index}`); |
|
const icon = document.getElementById(`icon-${index}`); |
|
const card = detailsDiv.closest('.card'); |
|
|
|
detailsDiv.classList.toggle('hidden'); |
|
card.classList.toggle('expanded'); |
|
|
|
if (detailsDiv.classList.contains('hidden')) { |
|
button.querySelector('span:last-child').textContent = 'Show Details'; |
|
icon.innerHTML = '<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>'; |
|
} else { |
|
button.querySelector('span:last-child').textContent = 'Hide Details'; |
|
icon.innerHTML = '<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path></svg>'; |
|
} |
|
} |
|
|
|
document.getElementById('filterTags').addEventListener('change', function() { |
|
const selectedTag = this.value; |
|
const filtered = selectedTag ? interactions.filter(interaction => interaction.tags.includes(selectedTag)) : interactions; |
|
renderConversations(filtered); |
|
}); |
|
|
|
// --- Precision Tracker View --- |
|
function initializePrecisionTracker() { |
|
// Precision Distribution Chart |
|
const precisionScores = interactions.map(interaction => interaction.precision); |
|
const precisionCounts = {}; |
|
precisionScores.forEach(score => { |
|
const bucket = Math.floor(score / 10) * 10; // Bucket scores into 10s (0-10, 11-20, etc.) |
|
precisionCounts[bucket] = (precisionCounts[bucket] || 0) + 1; |
|
}); |
|
const chartLabels = Object.keys(precisionCounts).sort((a, b) => parseInt(a) - parseInt(b)).map(bucket => `${bucket}-${parseInt(bucket) + 9}%`); |
|
const chartData = chartLabels.map(label => precisionCounts[parseInt(label.split('-')[0])]); |
|
|
|
const precisionChartRef = document.getElementById('precisionChart'); |
|
if (window.precisionChartInstance) { |
|
window.precisionChartInstance.destroy(); |
|
} |
|
|
|
const chartOptions = { |
|
responsive: true, |
|
maintainAspectRatio: true, |
|
scales: { |
|
y: { |
|
beginAtZero: true, |
|
grid: { |
|
color: 'rgba(0, 0, 0, 0.1)', |
|
borderColor: 'transparent' |
|
}, |
|
ticks: { |
|
font: { |
|
size: 14, |
|
} |
|
} |
|
}, |
|
x: { |
|
grid: { |
|
display: false |
|
}, |
|
ticks: { |
|
font: { |
|
size: 14, |
|
} |
|
} |
|
} |
|
}, |
|
plugins: { |
|
legend: { |
|
display: false |
|
}, |
|
tooltip: { |
|
enabled: true, |
|
backgroundColor: 'rgba(0, 0, 0, 0.8)', |
|
titleFont: { |
|
size: 16, |
|
weight: 'bold' |
|
}, |
|
bodyFont: { |
|
size: 14 |
|
}, |
|
padding: 10, |
|
titleColor: '#ffffff', |
|
bodyColor: '#ffffff', |
|
borderColor: 'rgba(0, 0, 0, 0.2)', |
|
borderWidth: 1, |
|
cornerRadius: 6 |
|
} |
|
} |
|
}; |
|
|
|
window.precisionChartInstance = new Chart(precisionChartRef, { |
|
type: 'bar', |
|
data: { |
|
labels: chartLabels, |
|
datasets: [{ |
|
label: 'Number of Interactions', |
|
data: chartData, |
|
backgroundColor: 'rgba(139, 92, 246, 0.7)', |
|
borderColor: '#8b5cf6', |
|
borderWidth: 1 |
|
}] |
|
}, |
|
options: { |
|
...chartOptions, |
|
} |
|
}); |
|
|
|
// Precision Metrics Breakdown |
|
const precisionMetricsDiv = document.getElementById('precisionMetrics'); |
|
precisionMetricsDiv.innerHTML = ''; |
|
interactions.forEach(interaction => { |
|
const metricItem = document.createElement('div'); |
|
metricItem.className = 'mb-4'; |
|
metricItem.innerHTML = ` |
|
<div class="flex items-center justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-900 dark:text-white">${interaction.programmer} - ${interaction.date}</span> |
|
<span class="text-sm font-medium text-gray-900 dark:text-white">${interaction.precision}%</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-3 dark:bg-gray-600"> |
|
<div class="bg-${interaction.precision >= 70 ? 'green' : interaction.precision >= 60 ? 'yellow' : 'red'}-600 h-3 rounded-full" style="width: ${interaction.precision}%"></div> |
|
</div> |
|
`; |
|
precisionMetricsDiv.appendChild(metricItem); |
|
}); |
|
|
|
// Add Learning Progress Section |
|
const learningProgress = document.createElement('div'); |
|
learningProgress.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
learningProgress.innerHTML = ` |
|
<div class="flex items-center justify-between mb-6"> |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Learning Progress</h3> |
|
<div class="flex items-center space-x-2"> |
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800"> |
|
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
|
</svg> |
|
Level 5 |
|
</span> |
|
</div> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Skills Progress</h4> |
|
<div class="space-y-4"> |
|
<div> |
|
<div class="flex justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Code Quality</span> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">85%</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"> |
|
<div class="bg-primary-600 h-2.5 rounded-full" style="width: 85%"></div> |
|
</div> |
|
</div> |
|
<div> |
|
<div class="flex justify-between mb-1"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Problem Solving</span> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">92%</span> |
|
</div> |
|
<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"> |
|
<div class="bg-primary-600 h-2.5 rounded-full" style="width: 92%"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Recent Achievements</h4> |
|
<div class="space-y-3"> |
|
<div class="flex items-center p-3 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex-shrink-0"> |
|
<svg class="w-6 h-6 text-yellow-400" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-10a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L11 3.414V9a1 1 0 11-2 0V3.414L5.707 6.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0112 2z" clip-rule="evenodd"/> |
|
</svg> |
|
</div> |
|
<div class="ml-3"> |
|
<p class="text-sm font-medium text-gray-900 dark:text-white">Code Optimization Master</p> |
|
<p class="text-xs text-gray-500 dark:text-gray-400">Improved performance by 50%</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('precision').appendChild(learningProgress); |
|
|
|
// Add Collaboration Insights |
|
const collaborationInsights = document.createElement('div'); |
|
collaborationInsights.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
collaborationInsights.innerHTML = ` |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-6">Collaboration Insights</h3> |
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6"> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<div class="flex items-center"> |
|
<div class="flex-shrink-0"> |
|
<svg class="w-8 h-8 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/> |
|
</svg> |
|
</div> |
|
<div class="ml-4"> |
|
<p class="text-lg font-semibold text-gray-900 dark:text-white">Team Impact</p> |
|
<p class="text-sm text-gray-500 dark:text-gray-400">+45% Knowledge Sharing</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('precision').appendChild(collaborationInsights); |
|
} |
|
|
|
// --- Rules & Feedback View --- |
|
function renderRuleImprovementsView() { |
|
const ruleImprovementsDiv = document.getElementById('ruleImprovements'); |
|
ruleImprovementsDiv.innerHTML = ''; |
|
const pendingRules = interactions.filter(interaction => interaction.ruleChange && interaction.ruleChange.status === 'pending'); |
|
|
|
if (pendingRules.length === 0) { |
|
ruleImprovementsDiv.innerHTML = '<p class="text-gray-700 dark:text-gray-300">No pending rule improvement suggestions.</p>'; |
|
return; |
|
} |
|
|
|
pendingRules.forEach((interaction, index) => { |
|
const ruleCard = document.createElement('div'); |
|
ruleCard.className = "mb-6 p-6 bg-white border border-gray-200 rounded-lg shadow-md dark:bg-gray-700 dark:border-gray-600"; |
|
ruleCard.innerHTML = ` |
|
<h5 class="text-xl font-bold leading-none text-primary-600 dark:text-primary-400">Rule Suggestion for: ${interaction.programmer} - ${interaction.date}</h5> |
|
<p class="mb-1 text-sm text-gray-500 dark:text-gray-400">Interaction Tags: ${interaction.tags.join(', ')}</p> |
|
<p class="font-normal text-gray-700 dark:text-gray-300"><span class="font-medium">Original Rule:</span> ${interaction.ruleChange.original}</p> |
|
<p class="font-normal text-gray-700 dark:text-gray-300"><span class="font-medium">Proposed Updated Rule:</span> ${interaction.ruleChange.updated}</p> |
|
<div class="mt-4 flex space-x-4"> |
|
<button onclick="approveRuleChange(${interactions.indexOf(interaction)})" type="button" class="text-white bg-secondary-700 hover:bg-secondary-800 focus:ring-4 focus:outline-none focus:ring-secondary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-secondary-600 dark:hover:bg-secondary-700 dark:focus:ring-secondary-800">Approve</button> |
|
<button onclick="rejectRuleChange(${interactions.indexOf(interaction)})" type="button" class="text-white bg-reddish-700 hover:bg-reddish-800 focus:ring-4 focus:outline-none focus:ring-reddish-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-reddish-600 dark:hover:bg-reddish-700 dark:focus:ring-reddish-800">Reject</button> |
|
</div> |
|
`; |
|
ruleImprovementsDiv.appendChild(ruleCard); |
|
}); |
|
|
|
// Add Code Quality Metrics |
|
const codeQualityMetrics = document.createElement('div'); |
|
codeQualityMetrics.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
codeQualityMetrics.innerHTML = ` |
|
<div class="flex items-center justify-between mb-6"> |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Code Quality Analysis</h3> |
|
<span class="px-3 py-1 text-sm font-medium rounded-full bg-green-100 text-green-800"> |
|
Healthy |
|
</span> |
|
</div> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Complexity Metrics</h4> |
|
<div class="space-y-4"> |
|
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Cyclomatic Complexity</span> |
|
<span class="text-sm font-medium text-green-600 dark:text-green-400">8/10</span> |
|
</div> |
|
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Maintainability Index</span> |
|
<span class="text-sm font-medium text-green-600 dark:text-green-400">85/100</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Technical Debt</h4> |
|
<div class="relative pt-1"> |
|
<div class="flex mb-2 items-center justify-between"> |
|
<div> |
|
<span class="text-xs font-semibold inline-block py-1 px-2 uppercase rounded-full text-green-600 bg-green-200"> |
|
Low Risk |
|
</span> |
|
</div> |
|
<div class="text-right"> |
|
<span class="text-xs font-semibold inline-block text-green-600"> |
|
2.5 days |
|
</span> |
|
</div> |
|
</div> |
|
<div class="overflow-hidden h-2 mb-4 text-xs flex rounded bg-green-200"> |
|
<div style="width:25%" class="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('rules').appendChild(codeQualityMetrics); |
|
|
|
// Add Security Analysis |
|
const securityAnalysis = document.createElement('div'); |
|
securityAnalysis.className = 'mt-8 p-6 bg-white rounded-lg shadow-lg dark:bg-gray-700'; |
|
securityAnalysis.innerHTML = ` |
|
<div class="flex items-center justify-between mb-6"> |
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">Security Analysis</h3> |
|
<div class="flex items-center space-x-2"> |
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800"> |
|
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
|
</svg> |
|
Secure |
|
</span> |
|
</div> |
|
</div> |
|
<div class="space-y-6"> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Dependency Check</h4> |
|
<div class="space-y-3"> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Dependencies Scanned</span> |
|
<span class="text-sm font-medium text-gray-900 dark:text-white">124</span> |
|
</div> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Vulnerabilities Found</span> |
|
<span class="text-sm font-medium text-green-600">0</span> |
|
</div> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Last Scan</span> |
|
<span class="text-sm font-medium text-gray-900 dark:text-white">2 hours ago</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="p-4 bg-gray-50 rounded-lg dark:bg-gray-800"> |
|
<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Security Best Practices</h4> |
|
<div class="space-y-2"> |
|
<div class="flex items-center"> |
|
<svg class="w-5 h-5 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
|
</svg> |
|
<span class="text-sm text-gray-700 dark:text-gray-300">Input Validation</span> |
|
</div> |
|
<div class="flex items-center"> |
|
<svg class="w-5 h-5 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
|
</svg> |
|
<span class="text-sm text-gray-700 dark:text-gray-300">Authentication</span> |
|
</div> |
|
<div class="flex items-center"> |
|
<svg class="w-5 h-5 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/> |
|
</svg> |
|
<span class="text-sm text-gray-700 dark:text-gray-300">Data Encryption</span> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
`; |
|
document.getElementById('rules').appendChild(securityAnalysis); |
|
} |
|
|
|
function approveRuleChange(interactionIndex) { |
|
interactions[interactionIndex].ruleChange.status = 'approved'; |
|
alert('Rule change approved!'); |
|
renderRuleImprovementsView(); |
|
renderConversations(); |
|
initializeDashboard(); |
|
} |
|
|
|
function rejectRuleChange(interactionIndex) { |
|
interactions[interactionIndex].ruleChange.status = 'rejected'; |
|
alert('Rule change rejected.'); |
|
renderRuleImprovementsView(); |
|
renderConversations(); |
|
initializeDashboard(); |
|
} |
|
|
|
// --- Initialize all views on page load --- |
|
document.addEventListener('DOMContentLoaded', () => { |
|
// Set default tab to Dashboard on load |
|
const defaultTabButton = document.getElementById('dashboard-tab'); |
|
const defaultTabContent = document.getElementById('dashboard'); |
|
defaultTabButton.classList.add('border-primary-500', 'text-primary-600', 'dark:text-primary-500', 'dark:border-primary-500', 'border-b-2'); |
|
defaultTabContent.classList.remove('hidden'); |
|
|
|
initializeDashboard(); |
|
renderConversations(); |
|
initializePrecisionTracker(); |
|
renderRuleImprovementsView(); |
|
|
|
// Simulate initial tab activation (Flowbite Tabs need explicit initialization sometimes post-render for dynamic content) |
|
const tabElements = document.querySelectorAll('#interactionTabs [role="tab"]'); |
|
tabElements.forEach(tab => { |
|
tab.addEventListener('click', () => { |
|
// Basic tab activation simulation, Flowbite may have its own API for dynamic tabs if needed |
|
tabElements.forEach(t => t.classList.remove('border-primary-500', 'text-primary-600', 'dark:text-primary-500', 'dark:border-primary-500', 'border-b-2')); |
|
tab.classList.add('border-primary-500', 'text-primary-600', 'dark:text-primary-500', 'dark:border-primary-500', 'border-b-2'); |
|
|
|
const targetId = tab.getAttribute('data-tabs-target'); |
|
document.querySelectorAll('#interactionTabContent > div').forEach(content => content.classList.add('hidden')); |
|
document.querySelector(targetId).classList.remove('hidden'); |
|
}); |
|
}); |
|
}); |
|
|
|
</script> |
|
|
|
</body> |
|
</html> |