Dashboard Status compact în Kanban

- Header colapsabil cu rezumat (ANAF, Git)
- Status row: ANAF, Git, ultimul raport cu timestamp
- Cron jobs pe un singur rând
- Colapsat by default
- status.json actualizat de rapoartele zilnice
This commit is contained in:
Echo
2026-01-30 14:55:39 +00:00
parent f371f579a1
commit 60dac72294
2 changed files with 254 additions and 0 deletions

View File

@@ -14,6 +14,126 @@
margin: 0 auto;
padding: var(--space-5);
}
/* Dashboard */
.dashboard {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
margin-bottom: var(--space-5);
overflow: hidden;
}
.dashboard-header {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3) var(--space-4);
background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(139, 92, 246, 0.1));
border-bottom: 1px solid var(--border);
cursor: pointer;
user-select: none;
}
.dashboard-header:hover {
filter: brightness(1.05);
}
.dashboard-title {
display: flex;
align-items: center;
gap: var(--space-2);
font-weight: 600;
font-size: var(--text-sm);
color: var(--text-primary);
}
.dashboard-title svg {
width: 16px;
height: 16px;
color: var(--accent);
}
.dashboard-summary {
flex: 1;
font-size: var(--text-xs);
color: var(--text-muted);
text-align: right;
}
.dashboard-toggle {
width: 16px;
height: 16px;
color: var(--text-muted);
transition: transform var(--transition-fast);
}
.dashboard.collapsed .dashboard-toggle {
transform: rotate(-90deg);
}
.dashboard.collapsed .dashboard-content {
display: none;
}
.dashboard-content {
padding: var(--space-2) var(--space-4);
}
.status-row {
display: flex;
flex-wrap: wrap;
gap: var(--space-4);
margin-bottom: var(--space-2);
}
.status-item {
display: flex;
align-items: center;
gap: var(--space-1);
font-size: var(--text-sm);
}
.status-label {
color: var(--text-muted);
}
.status-value {
font-weight: 600;
color: var(--text-primary);
}
.status-value.ok { color: #22c55e; }
.status-value.warning { color: #f59e0b; }
.status-value.error { color: #ef4444; }
.status-time {
font-size: var(--text-xs);
color: var(--text-muted);
margin-left: var(--space-1);
}
.cron-row {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
padding-top: var(--space-2);
border-top: 1px solid var(--border);
}
.cron-label {
color: var(--text-muted);
}
.cron-list {
color: var(--text-secondary);
}
.cron-done {
color: var(--text-muted);
text-decoration: line-through;
}
.page-header {
margin-bottom: var(--space-6);
@@ -352,6 +472,39 @@
</header>
<main class="main">
<!-- Status Dashboard -->
<div class="dashboard" id="dashboard">
<div class="dashboard-header" onclick="toggleDashboard()">
<div class="dashboard-title">
<i data-lucide="activity"></i>
<span>Status</span>
</div>
<div class="dashboard-summary" id="dashboardSummary">Se încarcă...</div>
<i data-lucide="chevron-down" class="dashboard-toggle" id="dashboardToggle"></i>
</div>
<div class="dashboard-content" id="dashboardContent">
<div class="status-row">
<div class="status-item">
<span class="status-label">ANAF:</span>
<span class="status-value" id="anafStatus">OK</span>
</div>
<div class="status-item">
<span class="status-label">Git:</span>
<span class="status-value" id="gitStatus">curat</span>
</div>
<div class="status-item">
<span class="status-label">Raport:</span>
<span class="status-value" id="lastReport">-</span>
<span class="status-time" id="reportTime"></span>
</div>
</div>
<div class="cron-row">
<span class="cron-label">Azi:</span>
<span class="cron-list" id="cronList">-</span>
</div>
</div>
</div>
<div class="page-header">
<h1 class="page-title">Task Board</h1>
<p class="page-subtitle" id="lastUpdated">Se încarcă...</p>
@@ -396,6 +549,86 @@
// Init Lucide icons
lucide.createIcons();
// Dashboard
function initDashboard() {
const collapsed = localStorage.getItem('dashboardCollapsed');
const dashboard = document.getElementById('dashboard');
// Default collapsed
if (collapsed === null || collapsed === 'true') {
dashboard.classList.add('collapsed');
}
loadDashboardStatus();
}
function toggleDashboard() {
const dashboard = document.getElementById('dashboard');
dashboard.classList.toggle('collapsed');
localStorage.setItem('dashboardCollapsed', dashboard.classList.contains('collapsed'));
}
async function loadDashboardStatus() {
try {
const response = await fetch('status.json?' + Date.now());
if (response.ok) {
const status = await response.json();
updateDashboard(status);
}
} catch (e) {
console.log('No status.json yet');
}
updateCronList();
}
function updateDashboard(status) {
// ANAF
const anafEl = document.getElementById('anafStatus');
if (status.anaf) {
anafEl.textContent = status.anaf.status;
anafEl.className = 'status-value ' + (status.anaf.ok ? 'ok' : 'warning');
}
// Git
const gitEl = document.getElementById('gitStatus');
if (status.git) {
gitEl.textContent = status.git.status;
gitEl.className = 'status-value ' + (status.git.clean ? 'ok' : 'warning');
}
// Last report
const reportEl = document.getElementById('lastReport');
const timeEl = document.getElementById('reportTime');
if (status.lastReport) {
reportEl.textContent = status.lastReport.summary || 'OK';
timeEl.textContent = status.lastReport.time ? '(' + status.lastReport.time + ')' : '';
}
// Summary in header
const summaryEl = document.getElementById('dashboardSummary');
let summary = [];
if (status.anaf) summary.push('ANAF: ' + status.anaf.status);
if (status.git) summary.push('Git: ' + status.git.status);
summaryEl.textContent = summary.join(' · ');
}
function updateCronList() {
const now = new Date();
const hour = now.getHours();
const jobs = [
{ time: '07:30', name: 'coaching', done: hour >= 8 },
{ time: '08:30', name: 'raport', done: hour >= 9 },
{ time: '20:00', name: 'raport', done: hour >= 20 },
{ time: '21:00', name: 'coaching', done: hour >= 21 }
];
const listEl = document.getElementById('cronList');
listEl.innerHTML = jobs.map(job =>
`<span class="${job.done ? 'cron-done' : ''}">${job.time} ${job.name}</span>`
).join(' · ');
}
initDashboard();
let tasksData = null;
let draggedTask = null;

21
kanban/status.json Normal file
View File

@@ -0,0 +1,21 @@
{
"anaf": {
"status": "OK",
"ok": true,
"lastCheck": "2026-01-30T13:50:00Z"
},
"git": {
"status": "curat",
"clean": true,
"files": 0
},
"agents": {
"count": 5,
"list": ["echo-work", "echo-health", "echo-growth", "echo-sprijin", "echo-scout"]
},
"lastReport": {
"type": "test",
"summary": "Ecosistem configurat, totul în ordine",
"time": "30 ian 2026, 13:55"
}
}