Files
nex/public/kan.html
2025-12-10 09:02:15 +01:00

432 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🎯 Interactive Tech Dashboard</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh; padding: 20px; color: #333;
}
.dashboard {
max-width: 1400px; margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px; padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
header { text-align: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 3px solid #667eea; }
h1 { font-size: 2.5em; color: #667eea; margin-bottom: 10px; font-weight: 700; }
.date { font-size: 1.2em; color: #666; font-weight: 500; }
.control-panel {
background: #f3f4f6; padding: 20px; border-radius: 15px;
margin-bottom: 30px; border: 2px dashed #9ca3af; position: relative;
}
.control-panel h3 { margin-bottom: 10px; color: #667eea; }
.control-textarea {
width: 100%; min-height: 150px; padding: 15px; border-radius: 8px;
border: 1px solid #d1d5db; font-family: 'Courier New', monospace; font-size: 0.9em;
resize: vertical; margin-bottom: 10px;
}
.control-hint {
font-size: 0.85em; color: #6b7280; font-family: monospace;
background: white; padding: 10px; border-radius: 5px; margin-top: 10px;
}
.save-indicator {
position: absolute; top: 10px; right: 10px;
background: #10b981; color: white; padding: 5px 10px;
border-radius: 5px; font-size: 0.8em; opacity: 0;
transition: opacity 0.3s ease;
}
.save-indicator.show { opacity: 1; }
.progress-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white; padding: 25px; border-radius: 15px;
margin-bottom: 30px; box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4);
}
.progress-label { display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 1.1em; font-weight: 500; }
.progress-bar { width: 100%; height: 30px; background: rgba(255, 255, 255, 0.3); border-radius: 15px; overflow: hidden; position: relative; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #4ade80 0%, #22c55e 100%); width: 25%; transition: width 0.5s ease; position: relative; box-shadow: 0 0 20px rgba(74, 222, 128, 0.5); }
.progress-fill::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); animation: shimmer 2s infinite; }
@keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
.projects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 25px; margin-bottom: 30px; }
.project-card { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; border-left: 5px solid; }
.project-card:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); }
.project-card.defrag { border-left-color: #667eea; }
.project-card.dual-boot { border-left-color: #f59e0b; }
.project-card.ai { border-left-color: #10b981; }
.project-card.autocomplete { border-left-color: #ef4444; }
.project-card.quick-actions { border-left-color: #8b5cf6; background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); }
.project-header { display: flex; align-items: center; margin-bottom: 20px; }
.project-icon { font-size: 2em; margin-right: 15px; }
h2 { font-size: 1.5em; color: #222; font-weight: 600; }
.task-item { display: flex; align-items: center; padding: 10px 0; border-bottom: 1px solid #e5e7eb; }
.task-item:last-child { border-bottom: none; }
.task-item:hover { background: #f9fafb; border-radius: 5px; margin: 0 -10px; padding: 10px; }
.task-checkbox { width: 18px; height: 18px; margin-right: 12px; cursor: pointer; accent-color: #667eea; }
.task-text { flex: 1; }
.task-text.completed { text-decoration: line-through; opacity: 0.6; }
.task-status { font-size: 0.85em; padding: 3px 10px; border-radius: 12px; margin-left: 10px; font-weight: 500; }
.status-todo { background: #f3f4f6; color: #666; }
.status-progress { background: #dbeafe; color: #1d4ed8; }
.status-completed { background: #dcfce7; color: #166534; }
.priority-badge { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-left: 10px; }
.priority-high { background: #ef4444; }
.priority-medium { background: #f59e0b; }
.priority-low { background: #10b981; }
.action-list { list-style: none; }
.action-list li { padding: 10px 0; display: flex; align-items: center; }
.action-checkbox { margin-right: 12px; width: 18px; height: 18px; cursor: pointer; accent-color: #f59e0b; }
.legend { background: #f9fafb; padding: 20px; border-radius: 15px; margin-bottom: 30px; display: flex; justify-content: space-around; flex-wrap: wrap; gap: 20px; }
.legend-item { display: flex; align-items: center; }
.notes { background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); padding: 20px; border-radius: 15px; border-left: 5px solid #f59e0b; }
.notes h3 { margin-bottom: 10px; color: #92400e; }
.notes ul { list-style-position: inside; color: #78350f; }
.footer { text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e5e7eb; color: #666; font-size: 0.9em; }
@media (max-width: 768px) { .projects-grid { grid-template-columns: 1fr; } h1 { font-size: 2em; } }
</style>
</head>
<body>
<div class="dashboard">
<header>
<h1>🎯 Interactive Tech Dashboard</h1>
<div class="date">December 10, 2025 | Focus: Infrastructure & AI</div>
</header>
<div class="control-panel">
<h3>🎮 Control Panel - Edit tasks below:</h3>
<div class="save-indicator" id="saveIndicator">✓ Saved to browser</div>
<textarea class="control-textarea" id="taskControl" placeholder="Enter tasks in format: PROJECT|Task description|status|priority|notes
Click 'Update Dashboard' to apply changes..."></textarea>
<button onclick="updateDashboard()" style="background: #667eea; color: white; padding: 10px 20px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; margin-right: 10px;">🔄 Update Dashboard</button>
<button onclick="resetToDefault()" style="background: #ef4444; color: white; padding: 10px 20px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; margin-right: 10px;">🔄 Reset to Default</button>
<button onclick="exportTasks()" style="background: #10b981; color: white; padding: 10px 20px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600;">📥 Export Tasks</button>
<div class="control-hint">
Format: PROJECT|Task|status|priority|notes<br>
PROJECT: DEFRAG, DUAL_BOOT, AI, AUTOCOMPLETE, QUICK_ACTIONS<br>
Status: todo, progress, completed<br>
Priority: high, medium, low (or blank)
</div>
</div>
<div class="progress-section">
<div class="progress-label">
<span>Overall Progress</span>
<span id="progressText">25% (2 of 8 tasks)</span>
</div>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
</div>
<div class="projects-grid" id="projectsGrid"></div>
<div class="legend">
<div class="legend-item">
<span class="status-badge status-todo">TODO</span>
<span style="margin-left: 10px;">Not started</span>
</div>
<div class="legend-item">
<span class="status-badge status-progress">PROGRESS</span>
<span style="margin-left: 10px;">Active</span>
</div>
<div class="legend-item">
<span class="status-badge status-completed">COMPLETED</span>
<span style="margin-left: 10px;">Done</span>
</div>
<div class="legend-item">
<span class="priority-badge priority-high"></span>
<span>High Priority</span>
</div>
<div class="legend-item">
<span class="priority-badge priority-medium"></span>
<span>Medium Priority</span>
</div>
<div class="legend-item">
<span class="priority-badge priority-low"></span>
<span>Low Priority</span>
</div>
</div>
<div class="notes">
<h3>💡 Notes</h3>
<ul>
<li>Focus on local machine maintenance first</li>
<li>Athena tasks blocked until disk cleanup complete</li>
<li>Mobile scraper requires network performance testing</li>
<li>Object detection model needs GPU verification</li>
</ul>
</div>
<div class="footer">
<p><strong>Next Review:</strong> End of day | <strong>ETA for completion:</strong> 2-3 days</p>
</div>
</div>
<script>
// Default task data
const DEFAULT_TASKS = `DEFRAG|App initialization|todo||local
DEFRAG|In-screen dynamic console|progress||local
DEFRAG|Disk cleanup tool integration|todo||local
DEFRAG|Athena monitoring dashboard|todo||athena
DUAL_BOOT|Partition disk space (50GB+)|todo|high|local
DUAL_BOOT|Install Ubuntu dual boot|todo|high|local
DUAL_BOOT|Configure boot loader|todo|medium|local
AI|Auctiora: Set up object detection pipeline|todo||local
AI|Auctiora: Test model inference|todo||local
AI|Scraper: Configure for mobile network|todo||mobile
AI|Scraper: Test connectivity & performance|todo||mobile
AUTOCOMPLETE|Deploy autocomplete API endpoint|todo||athena
AUTOCOMPLETE|Test integration with existing infrastructure|todo||athena
QUICK_ACTIONS|Free up disk space (50GB+)|todo||local
QUICK_ACTIONS|Install dual boot setup|todo||local
QUICK_ACTIONS|Migrate development environment|todo||local`;
let allTasks = [];
// Load from localStorage or use defaults
function loadTasks() {
const stored = localStorage.getItem('dashboardTasks');
if (stored) {
document.getElementById('taskControl').value = stored;
} else {
document.getElementById('taskControl').value = DEFAULT_TASKS;
saveToLocalStorage(); // Save defaults on first load
}
}
// Save to localStorage with visual feedback
function saveToLocalStorage() {
const value = document.getElementById('taskControl').value;
localStorage.setItem('dashboardTasks', value);
// Show save indicator
const indicator = document.getElementById('saveIndicator');
indicator.classList.add('show');
setTimeout(() => indicator.classList.remove('show'), 2000);
}
// Parse task data from control textarea
function parseTasks() {
const lines = document.getElementById('taskControl').value.trim().split('\n');
allTasks = [];
lines.forEach((line, index) => {
if (!line.trim()) return;
const parts = line.split('|').map(p => p.trim());
allTasks.push({
id: index,
project: parts[0] || 'MISC',
description: parts[1] || '',
status: parts[2] || 'todo',
priority: parts[3] || '',
notes: parts[4] || '',
rawLine: line
});
});
}
// Update progress bar
function updateProgress() {
const completed = allTasks.filter(t => t.status === 'completed').length;
const total = allTasks.length;
const percentage = total > 0 ? Math.round((completed / total) * 100) : 0;
document.getElementById('progressText').textContent = `${percentage}% (${completed} of ${total} tasks)`;
document.getElementById('progressFill').style.width = percentage + '%';
}
// Toggle task status
function toggleTask(taskId) {
const task = allTasks.find(t => t.id === taskId);
if (task) {
const statuses = ['todo', 'progress', 'completed'];
const currentIdx = statuses.indexOf(task.status);
task.status = statuses[(currentIdx + 1) % statuses.length];
// Update control textarea
updateControlTextarea();
// Save to localStorage
saveToLocalStorage();
// Re-render dashboard
renderDashboard();
}
}
// Update control textarea from task data
function updateControlTextarea() {
const lines = allTasks.map(task =>
`${task.project}|${task.description}|${task.status}|${task.priority}|${task.notes}`
);
document.getElementById('taskControl').value = lines.join('\n');
}
// Render the dashboard
function renderDashboard() {
parseTasks();
updateProgress();
const grid = document.getElementById('projectsGrid');
grid.innerHTML = '';
// Group tasks by project
const projects = {};
allTasks.forEach(task => {
if (!projects[task.project]) {
projects[task.project] = [];
}
projects[task.project].push(task);
});
// Project configurations
const projectConfig = {
'DEFRAG': { icon: '🔧', title: 'DEFRAG Application', color: 'defrag', subtitle: 'Disk optimization toolkit development' },
'DUAL_BOOT': { icon: '💻', title: 'Dual Boot Setup', color: 'dual-boot', subtitle: 'Unix/Linux workstation configuration' },
'AI': { icon: '🤖', title: 'AI/ML Projects', color: 'ai', subtitle: 'Artificial Intelligence & Machine Learning' },
'AUTOCOMPLETE': { icon: '✅', title: 'Autocomplete Service', color: 'autocomplete', subtitle: 'Athena server configuration' },
'QUICK_ACTIONS': { icon: '⚡', title: 'Quick Actions', color: 'quick-actions', subtitle: 'Immediate priority tasks' }
};
// Render each project
Object.entries(projects).forEach(([projectName, tasks]) => {
if (projectName === 'QUICK_ACTIONS') {
// Render quick actions as a special card
const quickActionsCard = document.createElement('div');
quickActionsCard.className = 'quick-actions';
quickActionsCard.innerHTML = `
<div class="project-header">
<span class="project-icon">⚡</span>
<h2>Quick Actions - Switch to Ubuntu</h2>
</div>
<ul class="action-list">
${tasks.map(task => `
<li>
<input type="checkbox" class="action-checkbox"
${task.status === 'completed' ? 'checked' : ''}
onchange="toggleTask(${task.id})">
<span class="${task.status === 'completed' ? 'task-text completed' : 'task-text'}">${task.description}</span>
</li>
`).join('')}
</ul>
`;
grid.appendChild(quickActionsCard);
} else {
const config = projectConfig[projectName] || { icon: '📌', title: projectName, color: 'misc', subtitle: '' };
const card = document.createElement('div');
card.className = `project-card ${config.color}`;
if (projectName === 'AI') {
// Special handling for AI project with subsections
const auctioraTasks = tasks.filter(t => t.description.includes('Auctiora'));
const scraperTasks = tasks.filter(t => t.description.includes('Scraper'));
card.innerHTML = `
<div class="project-header">
<span class="project-icon">${config.icon}</span>
<h2>${config.title}</h2>
</div>
${config.subtitle ? `<p style="color: #666; margin-bottom: 15px;">${config.subtitle}</p>` : ''}
<h3 style="margin: 15px 0 10px; color: #667eea;">Auctiora - Object Detection</h3>
${auctioraTasks.map(task => `
<div class="task-item">
<input type="checkbox" class="task-checkbox"
${task.status === 'completed' ? 'checked' : ''}
onchange="toggleTask(${task.id})">
<span class="${task.status === 'completed' ? 'task-text completed' : 'task-text'}">${task.description.replace('Auctiora: ', '')}</span>
<span class="task-status status-${task.status}">${task.status.toUpperCase()}</span>
</div>
`).join('')}
<h3 style="margin: 20px 0 10px; color: #667eea;">Mobile Scraper</h3>
${scraperTasks.map(task => `
<div class="task-item">
<input type="checkbox" class="task-checkbox"
${task.status === 'completed' ? 'checked' : ''}
onchange="toggleTask(${task.id})">
<span class="${task.status === 'completed' ? 'task-text completed' : 'task-text'}">${task.description.replace('Scraper: ', '')}</span>
<span class="task-status status-${task.status}">${task.status.toUpperCase()}</span>
</div>
`).join('')}
`;
} else {
// Standard project card
card.innerHTML = `
<div class="project-header">
<span class="project-icon">${config.icon}</span>
<h2>${config.title}</h2>
</div>
${config.subtitle ? `<p style="color: #666; margin-bottom: 15px;">${config.subtitle}</p>` : ''}
${tasks.map(task => `
<div class="task-item">
<input type="checkbox" class="task-checkbox"
${task.status === 'completed' ? 'checked' : ''}
onchange="toggleTask(${task.id})">
<span class="${task.status === 'completed' ? 'task-text completed' : 'task-text'}">${task.description}</span>
<span class="task-status status-${task.status}">${task.status.toUpperCase()}</span>
${task.priority ? `<span class="priority-badge priority-${task.priority}" title="${task.priority} priority"></span>` : ''}
${task.notes ? `<span style="margin-left: 8px; font-size: 0.85em; color: #6b7280;">(${task.notes})</span>` : ''}
</div>
`).join('')}
`;
}
grid.appendChild(card);
}
});
}
// Update dashboard from control textarea
function updateDashboard() {
saveToLocalStorage();
renderDashboard();
}
// Reset to default tasks
function resetToDefault() {
if (confirm('Are you sure you want to reset to default tasks? This will overwrite your current data.')) {
document.getElementById('taskControl').value = DEFAULT_TASKS;
saveToLocalStorage();
renderDashboard();
}
}
// Export tasks to clipboard
function exportTasks() {
const tasks = document.getElementById('taskControl').value;
navigator.clipboard.writeText(tasks).then(() => {
const indicator = document.getElementById('saveIndicator');
indicator.textContent = '✓ Copied to clipboard!';
indicator.classList.add('show');
setTimeout(() => {
indicator.textContent = '✓ Saved to browser';
indicator.classList.remove('show');
}, 2000);
});
}
// Initialize on load
window.onload = function() {
loadTasks();
renderDashboard();
};
</script>
</body>
</html>