frankenbot/templates/index.html

217 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<div class="hero-section">
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<div>
<h1 style="font-size:1.75rem;margin-bottom:.4rem;-webkit-text-fill-color:unset;background:none;color:var(--text-primary);">
Diversity-Ball Wien 2026
</h1>
<p style="color:var(--text-secondary);margin:0;font-size:.9rem;">
Agenten-Orchestrierung · Samstag 5. September · Wiener Rathaus
</p>
</div>
<div class="d-flex gap-2 flex-wrap">
<a href="/orchestrator" class="btn btn-primary">🤖 Orchestrator</a>
<a href="/chat" class="btn btn-secondary">💬 Chat</a>
<a href="/files" class="btn btn-secondary">📂 Dateien</a>
</div>
</div>
</div>
<!-- Stats -->
<div class="row g-3 mb-4">
<div class="col-6 col-md-3">
<div class="stat-card">
<div class="stat-number">{{ agents|length }}</div>
<div class="stat-label">Agenten</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div class="stat-number">{{ recent_tasks|length }}</div>
<div class="stat-label">Letzte Tasks</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div class="stat-number">5. Sep</div>
<div class="stat-label">Event-Datum</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div class="stat-number">3.500</div>
<div class="stat-label">Gäste</div>
</div>
</div>
</div>
<!-- Agents -->
<div class="d-flex align-items-center justify-content-between mb-3">
<h3 style="margin:0;">Verfügbare Agenten</h3>
<a href="/agents" class="btn btn-outline-secondary btn-sm">Alle verwalten</a>
</div>
<div class="row g-3 mb-4">
{% for key, agent in agents.items() %}
<div class="col-sm-6 col-md-4 col-lg-3">
<div class="card agent-card h-100">
<div class="card-body">
<div class="d-flex align-items-center gap-2 mb-2">
<span style="width:8px;height:8px;border-radius:50%;background:var(--success);flex-shrink:0;box-shadow:0 0 6px var(--success);"></span>
<h5 style="margin:0;font-size:.875rem;font-weight:600;">{{ agent.name }}</h5>
</div>
<p style="font-size:.775rem;color:var(--text-muted);line-height:1.45;margin-bottom:.75rem;">
{{ agent.description[:90] }}{% if agent.description|length > 90 %}…{% endif %}
</p>
<span class="badge bg-success">aktiv</span>
</div>
<div class="card-footer">
<a href="/agents?edit={{ key }}" class="btn btn-outline-primary btn-sm w-100">⚙ Bearbeiten</a>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- System-Steuerung -->
<div class="card mb-4">
<div class="card-body">
<h5 style="margin-bottom:1rem;font-weight:600;">System-Steuerung</h5>
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
<!-- Daily Standup Toggle -->
<div class="d-flex align-items-center gap-3">
<div>
<div style="font-weight:500;font-size:.9rem;">Daily Standup</div>
<div style="font-size:.78rem;color:var(--text-muted);">Täglich 09:00 automatische Statusabfrage</div>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" role="switch" id="standupToggle"
{% if standup_enabled %}checked{% endif %}
style="width:2.5em;height:1.4em;cursor:pointer;">
</div>
<span id="standupLabel" class="badge {% if standup_enabled %}bg-success{% else %}bg-secondary{% endif %}">
{% if standup_enabled %}Aktiv{% else %}Inaktiv{% endif %}
</span>
</div>
<!-- Tasks leeren -->
<button id="clearTasksBtn" class="btn btn-outline-danger btn-sm" onclick="clearAllTasks()">
Alle Tasks leeren
</button>
</div>
</div>
</div>
<!-- Recent Tasks -->
{% if recent_tasks %}
<div class="d-flex align-items-center justify-content-between mb-3">
<h3 style="margin:0;">Letzte Tasks</h3>
<a href="/tasks" class="btn btn-outline-secondary btn-sm">Alle Tasks</a>
</div>
<div class="card">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>#</th>
<th>Titel</th>
<th>Agent</th>
<th>Status</th>
<th>Erstellt</th>
</tr>
</thead>
<tbody>
{% for task in recent_tasks %}
<tr>
<td><span style="color:var(--text-muted);font-size:.8rem;">#{{ task.id }}</span></td>
<td style="font-weight:500;">{{ task.title }}</td>
<td style="font-size:.8rem;color:var(--text-muted);">{{ task.assigned_agent }}</td>
<td>
{% if task.status == 'pending' %}
<span class="badge bg-warning">Pending</span>
{% elif task.status == 'in_progress' %}
<span class="badge bg-primary">Läuft</span>
{% elif task.status == 'completed' %}
<span class="badge bg-success">Fertig</span>
{% elif task.status == 'error' %}
<span class="badge bg-danger">Fehler</span>
{% else %}
<span class="badge bg-secondary">{{ task.status }}</span>
{% endif %}
</td>
<td style="color:var(--text-muted);font-size:.78rem;">{{ task.created }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<script>
// Daily Standup Toggle
document.getElementById('standupToggle').addEventListener('change', function() {
const enabled = this.checked;
const label = document.getElementById('standupLabel');
fetch('/api/standup/toggle', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({enabled: enabled})
})
.then(r => r.json())
.then(data => {
if (data.success) {
label.textContent = enabled ? 'Aktiv' : 'Inaktiv';
label.className = 'badge ' + (enabled ? 'bg-success' : 'bg-secondary');
} else {
// Revert on error
this.checked = !enabled;
alert('Fehler: ' + data.message);
}
})
.catch(() => {
this.checked = !enabled;
alert('Netzwerkfehler beim Speichern.');
});
});
// Alle Tasks leeren
function clearAllTasks() {
if (!confirm('Alle Tasks wirklich löschen? Dies kann nicht rückgängig gemacht werden.')) return;
const btn = document.getElementById('clearTasksBtn');
btn.disabled = true;
btn.textContent = 'Löschen...';
fetch('/api/tasks/clear', {method: 'POST'})
.then(r => r.json())
.then(data => {
if (data.success) {
// Task-Tabelle aus DOM entfernen falls vorhanden
const taskSection = document.querySelector('.table-responsive');
if (taskSection) taskSection.closest('.card').remove();
const taskHeader = document.querySelectorAll('h3');
taskHeader.forEach(h => { if (h.textContent.includes('Letzte Tasks')) h.closest('.d-flex').remove(); });
btn.textContent = 'Geleert';
btn.className = 'btn btn-success btn-sm';
setTimeout(() => {
btn.textContent = 'Alle Tasks leeren';
btn.className = 'btn btn-outline-danger btn-sm';
btn.disabled = false;
}, 2000);
} else {
alert('Fehler: ' + data.message);
btn.disabled = false;
btn.textContent = 'Alle Tasks leeren';
}
})
.catch(() => {
alert('Netzwerkfehler.');
btn.disabled = false;
btn.textContent = 'Alle Tasks leeren';
});
}
</script>
{% endblock %}