Website (14 monoliths split): - compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20) - quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11) - i18n.ts (1,173 → 8 language files) - unity-bridge (1,094 → 12), backlog (1,087 → 6) - training (1,066 → 8), rag (1,063 → 8) - Deleted index_original.ts (4,899 LOC dead backup) Studio-v2 (5 monoliths split): - meet/page.tsx (1,481 → 9), messages (1,166 → 9) - AlertsB2BContext.tsx (1,165 → 5 modules) - alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6) All existing imports preserved. Zero new TypeScript errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
3.4 KiB
TypeScript
81 lines
3.4 KiB
TypeScript
'use client'
|
|
|
|
import type { AlertItem, Topic, Stats } from './types'
|
|
import { getScoreBadge } from './useAlertsData'
|
|
|
|
interface DashboardTabProps {
|
|
stats: Stats | null
|
|
topics: Topic[]
|
|
alerts: AlertItem[]
|
|
error: string | null
|
|
}
|
|
|
|
export default function DashboardTab({ stats, topics, alerts, error }: DashboardTabProps) {
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Stats Grid */}
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
|
<div className="text-3xl font-bold text-slate-900">{stats?.total_alerts || 0}</div>
|
|
<div className="text-sm text-slate-500">Alerts gesamt</div>
|
|
</div>
|
|
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
|
<div className="text-3xl font-bold text-blue-600">{stats?.new_alerts || 0}</div>
|
|
<div className="text-sm text-slate-500">Neue Alerts</div>
|
|
</div>
|
|
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
|
<div className="text-3xl font-bold text-green-600">{stats?.kept_alerts || 0}</div>
|
|
<div className="text-sm text-slate-500">Relevant</div>
|
|
</div>
|
|
<div className="bg-white rounded-xl border border-slate-200 p-4">
|
|
<div className="text-3xl font-bold text-amber-600">{stats?.review_alerts || 0}</div>
|
|
<div className="text-sm text-slate-500">Zur Pruefung</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Quick Actions */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<h3 className="font-semibold text-slate-900 mb-4">Aktive Topics</h3>
|
|
<div className="space-y-3">
|
|
{topics.slice(0, 5).map((topic) => (
|
|
<div key={topic.id} className="flex items-center justify-between p-3 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<div className="font-medium text-slate-900">{topic.name}</div>
|
|
<div className="text-xs text-slate-500">{topic.alert_count} Alerts</div>
|
|
</div>
|
|
<span className={`px-2 py-1 rounded text-xs font-semibold ${topic.is_active ? 'bg-green-100 text-green-800' : 'bg-slate-100 text-slate-600'}`}>
|
|
{topic.is_active ? 'Aktiv' : 'Pausiert'}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6">
|
|
<h3 className="font-semibold text-slate-900 mb-4">Letzte Alerts</h3>
|
|
<div className="space-y-3">
|
|
{alerts.slice(0, 5).map((alert) => (
|
|
<div key={alert.id} className="p-3 bg-slate-50 rounded-lg">
|
|
<div className="font-medium text-slate-900 text-sm truncate">{alert.title}</div>
|
|
<div className="flex items-center gap-2 mt-1">
|
|
<span className="text-xs text-slate-500">{alert.topic_name}</span>
|
|
{getScoreBadge(alert.relevance_score)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
|
|
<p className="text-sm text-amber-800">
|
|
<strong>Hinweis:</strong> API nicht erreichbar. Demo-Daten werden angezeigt.
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|