/* Intelligence Dashboard — Seite A
Shows: Agent status, all simulations, conflict alerts, custom report trigger */
const { useState: useStateI, useEffect: useEffectI } = React;
function fmtTime(iso) {
if (!iso) return '—';
const d = new Date(iso);
return d.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
}
function nextRunTimes() {
const now = new Date();
const noon = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 12, 0, 0));
const midnight = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1, 0, 0, 0));
const next = now < noon ? noon : midnight;
return next.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
}
/* ---------- Agent status bar ---------- */
function AgentBar({ agentData, onTrigger, triggering }) {
const last = agentData?.last_run;
return (
{/* Last run */}
Letzter Run
{last ? (
<>
{fmtTime(last.finished_at || last.started_at)}
· {last.sims_updated ?? 0} Sims · {last.new_conflicts ?? 0} Konflikte
>
) : (
Kein Run verfügbar
)}
{/* Next run */}
Nächster Run
{nextRunTimes()} UTC
(tägl. 00:00 + 12:00)
{/* Trigger button */}
);
}
/* ---------- Simulation card ---------- */
function SimCard({ sim }) {
const pct = Math.round((sim.dominant_probability ?? 0) * 100);
return (
{sim.sim_id}
{fmtTime(sim.last_updated)}
{sim.dominant_scenario}
{pct}%
{sim.scenario_count} Szenarien · {sim.rounds_completed} Runden
{/* Mini probability bar */}
Detail öffnen →
);
}
/* ---------- Conflict alert list ---------- */
function ConflictAlerts({ conflicts }) {
if (!conflicts || conflicts.length === 0) return null;
return (
Neu erkannte Konflikte
{conflicts.length} Einträge
{conflicts.slice(0, 8).map((c) => (
{c.topic}
{fmtTime(c.detected_at)}
{c.status === 'simulation_created' ? ' · Simulation erstellt' : ' · Fehlgeschlagen'}
{c.sim_id && (
Report →
)}
))}
);
}
/* ---------- Intelligence Dashboard root ---------- */
function IntelligenceDashboard() {
const [agentData, setAgentData] = useStateI(null);
const [sims, setSims] = useStateI([]);
const [conflicts, setConflicts] = useStateI([]);
const [loading, setLoading] = useStateI(true);
const [triggering, setTriggering] = useStateI(false);
const [triggerMsg, setTriggerMsg] = useStateI('');
const [showOptimizer, setShowOptimizer] = useStateI(false);
const [customPrompt] = useStateI('');
const load = async () => {
try {
const [agent, simsRes, conflictsRes] = await Promise.all([
window.RICS_API.getAgentStatus().catch(() => null),
window.RICS_API.getLiveReports().catch(() => []),
window.RICS_API.getConflicts(20).catch(() => []),
]);
setAgentData(agent);
setSims(Array.isArray(simsRes) ? simsRes : []);
setConflicts(Array.isArray(conflictsRes) ? conflictsRes : []);
} finally {
setLoading(false);
}
};
useEffectI(() => { load(); }, []);
const handleTrigger = async () => {
setTriggering(true);
setTriggerMsg('');
try {
await window.RICS_API.triggerAgent();
setTriggerMsg('Agent wurde gestartet. Daten in ~10 Minuten aktualisiert.');
setTimeout(load, 5000);
} catch (e) {
setTriggerMsg('Fehler: ' + e.message);
} finally {
setTriggering(false);
}
};
return (
{showOptimizer && (
setShowOptimizer(false)}
onLaunched={(simId) => { window.location.href = `simulation.html?id=${simId}`; }}
/>
)}
{/* Breadcrumb */}
{/* Header */}
Intelligence
{loading ? 'Daten werden geladen…' : `${sims.length} aktive Simulationen.`}
Täglich aktualisiert.
{/* Agent status bar */}
{!loading && (
)}
{triggerMsg && (
{triggerMsg}
)}
{/* Conflict alerts */}
{!loading &&
}
{/* Simulations grid */}
{loading ? (
Simulationen werden geladen…
) : sims.length === 0 ? (
Noch keine Simulationen vorhanden.
) : (
Alle Simulationen · {sims.length} aktiv
{sims.map((s) => )}
)}
);
}
ReactDOM.createRoot(document.getElementById('root')).render();