Initial commit: Nexus Mission Control Platform

- ASP.NET Core 10 Backend (JWT Auth, Agent config API)
- Vue 3 Frontend (Dashboard, Team, Agents, Config Editor)
- PostgreSQL Database
- Docker Compose setup
- Mission Control Dashboard redesign
This commit is contained in:
Bao
2026-06-09 16:31:42 +02:00
commit eeb6174de0
248 changed files with 19706 additions and 0 deletions
@@ -0,0 +1,187 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Clock } from '@lucide/vue'
type InitiativeStatus = 'healthy' | 'attention' | 'blocked' | 'paused' | 'completed'
interface Initiative {
title: string
progress: number
openTasks: number
blockers: number
status: InitiativeStatus
lastActivity: string
}
const initiatives = ref<Initiative[]>([
{ title: 'OpenClaw Companion', progress: 55, openTasks: 7, blockers: 2, status: 'healthy', lastActivity: 'vor 8 Minuten' },
{ title: '2D Idle Game', progress: 42, openTasks: 4, blockers: 0, status: 'healthy', lastActivity: 'vor 2 Stunden' },
{ title: 'Deutsch B2', progress: 73, openTasks: 3, blockers: 0, status: 'attention', lastActivity: 'vor 1 Stunde' },
{ title: 'Nexus Dashboard', progress: 60, openTasks: 3, blockers: 0, status: 'healthy', lastActivity: 'vor 5 Minuten' },
])
const statusMeta: Record<InitiativeStatus, { label: string; color: string; bg: string }> = {
healthy: { label: 'Healthy', color: '#22c55e', bg: 'rgba(34,197,94,0.1)' },
attention: { label: 'Needs Attention', color: '#eab308', bg: 'rgba(234,179,8,0.1)' },
blocked: { label: 'Blocked', color: '#ef4444', bg: 'rgba(239,68,68,0.1)' },
paused: { label: 'Paused', color: '#6b7280', bg: 'rgba(107,114,128,0.1)' },
completed: { label: 'Completed', color: '#3b82f6', bg: 'rgba(59,130,246,0.1)' },
}
</script>
<template>
<div class="initiatives-section">
<h2>Active Initiatives</h2>
<div class="initiatives-grid">
<div
v-for="(init, idx) in initiatives"
:key="idx"
:class="['initiative-card', 'status-' + init.status]"
>
<div class="init-head">
<h3>{{ init.title }}</h3>
<span
class="status-badge"
:style="{
color: statusMeta[init.status].color,
background: statusMeta[init.status].bg,
}"
>
{{ statusMeta[init.status].label }}
</span>
</div>
<div class="progress-bar">
<div
class="progress-fill"
:style="{ width: init.progress + '%' }"
></div>
</div>
<div class="progress-label">{{ init.progress }}%</div>
<div class="init-stats">
<span>{{ init.openTasks }} offene Aufgaben</span>
<span v-if="init.blockers">&middot; {{ init.blockers }} Blocker</span>
</div>
<div class="init-meta">
<Clock :size="11" />
<span>Letzte Aktivität {{ init.lastActivity }}</span>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.initiatives-section {
display: flex;
flex-direction: column;
gap: 10px;
padding: 18px;
background: rgba(22, 27, 34, 0.8);
border: 1px solid rgba(139, 124, 246, 0.12);
border-radius: 16px;
box-shadow: 0 4px 24px rgba(0,0,0,0.3);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
transition: all 0.2s ease;
}
.initiatives-section:hover {
border-color: rgba(139, 124, 246, 0.18);
}
.initiatives-section h2 {
font-size: 14px;
font-weight: 600;
margin: 0;
color: #e8eaf0;
}
.initiatives-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 10px;
}
.initiative-card {
background: rgba(13, 17, 23, 0.5);
border: 1px solid rgba(139, 124, 246, 0.08);
border-radius: 14px;
padding: 14px;
transition: all 0.2s ease;
}
.initiative-card:hover {
border-color: rgba(139, 124, 246, 0.2);
box-shadow: 0 2px 12px rgba(0,0,0,0.2);
}
.init-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
gap: 8px;
}
.init-head h3 {
font-size: 12px;
font-weight: 600;
margin: 0;
color: #e8eaf0;
}
.status-badge {
font-size: 8px;
font-weight: 700;
padding: 2px 7px;
border-radius: 12px;
white-space: nowrap;
flex-shrink: 0;
letter-spacing: 0.02em;
}
.progress-bar {
height: 4px;
background: rgba(139, 124, 246, 0.1);
border-radius: 4px;
margin-bottom: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
border-radius: 4px;
background: linear-gradient(90deg, #a78bfa, #8b5cf6);
transition: width 0.5s ease;
}
.initiative-card.status-attention .progress-fill {
background: linear-gradient(90deg, #eab308, #f59e0b);
}
.initiative-card.status-blocked .progress-fill {
background: linear-gradient(90deg, #ef4444, #dc2626);
}
.progress-label {
font-size: 10px;
color: #6b7385;
margin-bottom: 4px;
}
.init-stats {
font-size: 9px;
color: #6b7385;
margin-bottom: 4px;
display: flex;
gap: 4px;
flex-wrap: wrap;
}
.init-meta {
display: flex;
align-items: center;
gap: 4px;
font-size: 9px;
color: #6b7385;
}
.init-meta svg {
flex-shrink: 0;
}
@media (max-width: 900px) {
.initiatives-grid {
grid-template-columns: 1fr 1fr;
}
}
@media (max-width: 600px) {
.initiatives-grid {
grid-template-columns: 1fr;
}
}
</style>