"use client"; import { useState, useEffect, useCallback } from "react"; import Link from "next/link"; import Card from "@/components/ui/Card"; interface MarketData { btc?: string; eth?: string; sol?: string; btcChange?: string; ethChange?: string; solChange?: string; } interface MorningBrief { id: number; date: string; location: string; weather: string; marketData: MarketData; aiNewsHeadlines: string[]; skillsToLearn: string[]; euAiActStatus: string; sitementeStatus: { serverUptime?: string; demoPages?: string; leadStatus?: string }; warmLeads: { name: string; business: string; note: string }[]; dayPriorities: string[]; skippedTasks: string[]; autoExecutionSummary: string; } interface CompletedTask { task: string; completed: boolean; } interface ProjectProgress { project: string; progress: number; } interface EodBrief { id: number; date: string; marketUpdate: MarketData; completedTasks: CompletedTask[]; tomorrowPriorities: string[]; councilFeedback: Record; projectProgress: ProjectProgress[]; } interface Bug { description: string; severity: string; status: string; } interface AmunSession { id: number; date: string; testsRun: string[]; bugsFound: Bug[]; codeQualityScore: number; recommendations: string[]; } function changeColor(val?: string) { if (!val) return "text-slate-500"; const n = parseFloat(val); if (isNaN(n)) return "text-slate-500"; return n >= 0 ? "text-emerald-400" : "text-red-400"; } function progressColor(p: number) { if (p >= 80) return "bg-emerald-500"; if (p >= 50) return "bg-amber-500"; if (p >= 25) return "bg-orange-500"; return "bg-red-500"; } function buildSnapshot(morning?: MorningBrief, eod?: EodBrief, amun?: AmunSession): string { const parts: string[] = []; if (morning) { const date = new Date(morning.date + "T12:00:00").toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long", }); parts.push(`πŸ“… **${date}** β€” ${morning.location}, ${morning.weather}.`); const md = morning.marketData; if (md?.btc) { const btcStr = md.btcChange ? `BTC at ${md.btc} (${parseFloat(md.btcChange) >= 0 ? "+" : ""}${md.btcChange}%)` : `BTC at ${md.btc}`; const ethStr = md.eth ? `, ETH at ${md.eth}` : ""; const solStr = md.sol ? `, SOL at ${md.sol}` : ""; parts.push(`πŸ“ˆ Markets: ${btcStr}${ethStr}${solStr}.`); } const headlines = morning.aiNewsHeadlines?.filter((h) => h.trim()) || []; if (headlines.length > 0) { parts.push(`πŸ€– AI News: ${headlines.slice(0, 2).join("; ")}.`); } const priorities = morning.dayPriorities?.filter((p) => p.trim()) || []; if (priorities.length > 0) { parts.push(`⚑ ${priorities.length} priorities set. Top: "${priorities[0]}".`); } const skipped = morning.skippedTasks?.filter((t) => t.trim()) || []; if (skipped.length > 0) { parts.push(`⏭ ${skipped.length} task(s) carried over from yesterday.`); } if (morning.autoExecutionSummary?.trim()) { parts.push(`πŸ¦… Horus auto-executing: ${morning.autoExecutionSummary.slice(0, 120)}${morning.autoExecutionSummary.length > 120 ? "…" : ""}`); } } if (eod) { const completed = eod.completedTasks?.filter((t) => t.completed) || []; const total = eod.completedTasks?.length || 0; if (total > 0) { parts.push(`βœ… EOD: ${completed.length}/${total} tasks completed.`); } const cf = eod.councilFeedback || {}; if (cf.horus) parts.push(`πŸ¦… Horus: "${cf.horus}"`); if (cf.amun) parts.push(`βš™οΈ Amun: "${cf.amun}"`); } if (amun) { const openBugs = amun.bugsFound?.filter((b) => b.status === "open") || []; const tests = amun.testsRun?.filter((t) => t.trim()) || []; parts.push( `πŸ§ͺ Amun: ${tests.length} test(s) run, ${openBugs.length} open bug(s), code quality ${amun.codeQualityScore}%.` ); } if (parts.length === 0) { return "No data logged yet. Start by filing a Morning Brief."; } return parts.join(" "); } export default function MissionControlPage() { const [morning, setMorning] = useState(null); const [eod, setEod] = useState(null); const [amun, setAmun] = useState(null); const [loading, setLoading] = useState(true); const loadLatest = useCallback(async () => { setLoading(true); try { const [mRes, eRes, aRes] = await Promise.all([ fetch("/api/morning?limit=1"), fetch("/api/eod?limit=1"), fetch("/api/amun?limit=1"), ]); const [mData, eData, aData] = await Promise.all([mRes.json(), eRes.json(), aRes.json()]); const parseJson = (val: unknown, fallback: T): T => { if (typeof val === "string") { try { return JSON.parse(val) as T; } catch { return fallback; } } return (val as T) ?? fallback; }; if (Array.isArray(mData) && mData[0]) { const m = mData[0]; setMorning({ ...m, marketData: parseJson(m.marketData, {}), aiNewsHeadlines: parseJson(m.aiNewsHeadlines, []), skillsToLearn: parseJson(m.skillsToLearn, []), sitementeStatus: parseJson(m.sitementeStatus, {}), warmLeads: parseJson(m.warmLeads, []), dayPriorities: parseJson(m.dayPriorities, []), skippedTasks: parseJson(m.skippedTasks, []), }); } if (Array.isArray(eData) && eData[0]) { const e = eData[0]; setEod({ ...e, marketUpdate: parseJson(e.marketUpdate, {}), completedTasks: parseJson(e.completedTasks, []), tomorrowPriorities: parseJson(e.tomorrowPriorities, []), councilFeedback: parseJson(e.councilFeedback, {}), projectProgress: parseJson(e.projectProgress, []), }); } if (Array.isArray(aData) && aData[0]) { const a = aData[0]; setAmun({ ...a, testsRun: parseJson(a.testsRun, []), bugsFound: parseJson(a.bugsFound, []), recommendations: parseJson(a.recommendations, []), }); } } catch { // ignore } finally { setLoading(false); } }, []); useEffect(() => { loadLatest(); }, [loadLatest]); const snapshot = buildSnapshot(morning ?? undefined, eod ?? undefined, amun ?? undefined); if (loading) { return (

Loading Mission Control…

); } const noData = !morning && !eod && !amun; return (
{/* Header */}

β–Ά Horus Mission Control

Latest intelligence snapshot across all agents

{noData ? (

No briefs logged yet.

β˜€ Log Morning Brief πŸŒ™ Log EOD Brief
) : (
{/* Today Snapshot */}
H

Today Snapshot β€” Horus Narrative

{snapshot.replace(/ (πŸ“…|πŸ“ˆ|πŸ€–|⚑|⏭|πŸ¦…|βœ…|πŸ§ͺ)/g, "\n$1")}

{/* Morning Brief Summary */} {morning && ( <>
Morning Brief
{morning.date}
{/* Location & Weather */}
πŸ“ {morning.location} 🌀 {morning.weather} πŸ‡ͺπŸ‡Ί {morning.euAiActStatus}
{/* Market */} {(morning.marketData?.btc || morning.marketData?.eth || morning.marketData?.sol) && (

Market

{(["btc", "eth", "sol"] as const).map((coin) => { const price = morning.marketData[coin]; const change = morning.marketData[`${coin}Change` as keyof MarketData]; if (!price) return null; return (
{coin} {price} {change && ( {parseFloat(change) >= 0 ? "+" : ""}{change}% )}
); })}
)} {/* AI News */} {morning.aiNewsHeadlines?.filter((h) => h.trim()).length > 0 && (

AI News

    {morning.aiNewsHeadlines.filter((h) => h.trim()).map((h, i) => (
  • β€’ {h}
  • ))}
)} {/* Priorities */} {morning.dayPriorities?.filter((p) => p.trim()).length > 0 && (

Day Priorities

    {morning.dayPriorities.filter((p) => p.trim()).map((p, i) => (
  1. {i + 1}. {p}
  2. ))}
)} {/* Skipped Tasks */} {morning.skippedTasks?.filter((t) => t.trim()).length > 0 && (

Skipped Tasks

    {morning.skippedTasks.filter((t) => t.trim()).map((t, i) => (
  • ⏭ {t}
  • ))}
)} {/* Auto-Execution */} {morning.autoExecutionSummary?.trim() && (

Auto-Execution

πŸ¦… {morning.autoExecutionSummary}

)}
)} {/* EOD Brief Summary */} {eod && ( <>
End-of-Day Brief
{eod.date}
{/* Market Update */} {(eod.marketUpdate?.btc || eod.marketUpdate?.eth || eod.marketUpdate?.sol) && (

Market Update

{(["btc", "eth", "sol"] as const).map((coin) => { const price = eod.marketUpdate[coin]; const change = eod.marketUpdate[`${coin}Change` as keyof MarketData]; if (!price) return null; return (
{coin} {price} {change && ( {parseFloat(change) >= 0 ? "+" : ""}{change}% )}
); })}
)} {/* Completed Tasks */} {eod.completedTasks?.filter((t) => t.task.trim()).length > 0 && (

Completed Tasks ({eod.completedTasks.filter((t) => t.completed).length}/{eod.completedTasks.filter((t) => t.task.trim()).length})

    {eod.completedTasks.filter((t) => t.task.trim()).map((t, i) => (
  • {t.completed ? "βœ“" : "β—‹"} {t.task}
  • ))}
)} {/* Tomorrow Priorities */} {eod.tomorrowPriorities?.filter((p) => p.trim()).length > 0 && (

Tomorrow's Priorities

    {eod.tomorrowPriorities.filter((p) => p.trim()).map((p, i) => (
  1. {i + 1}. {p}
  2. ))}
)} {/* Council Feedback */} {Object.keys(eod.councilFeedback || {}).filter((k) => eod.councilFeedback[k]?.trim()).length > 0 && (

Council Feedback

{Object.entries(eod.councilFeedback).filter(([, v]) => v?.trim()).map(([agent, feedback]) => (
{agent === "horus" ? "πŸ¦…" : agent === "amun" ? "βš™οΈ" : "πŸ€–"} {agent}: “{feedback}”
))}
)} {/* Project Progress */} {eod.projectProgress?.filter((p) => p.project.trim()).length > 0 && (

Project Progress

{eod.projectProgress.filter((p) => p.project.trim()).map((proj) => (
{proj.project} {proj.progress}%
))}
)}
)} {/* Amun Session Summary */} {amun && ( <>
Amun Dev Session
{amun.date}
{/* Stats */}

Tests Run

{amun.testsRun?.filter((t) => t.trim()).length || 0}

Open Bugs

b.status === "open").length > 0 ? "text-red-400" : "text-emerald-400"}`}> {amun.bugsFound?.filter((b) => b.status === "open").length || 0}

Code Quality

= 80 ? "text-emerald-400" : amun.codeQualityScore >= 60 ? "text-amber-400" : "text-red-400"}`}> {amun.codeQualityScore}%

{/* Tests */} {amun.testsRun?.filter((t) => t.trim()).length > 0 && (

Tests

{amun.testsRun.filter((t) => t.trim()).map((t, i) => ( {t} ))}
)} {/* Bugs */} {amun.bugsFound?.length > 0 && (

Bugs Found

{amun.bugsFound.map((bug, i) => (
{bug.severity} {bug.description} {bug.status}
))}
)} {/* Recommendations */} {amun.recommendations?.filter((r) => r.trim()).length > 0 && (

Recommendations

    {amun.recommendations.filter((r) => r.trim()).map((r, i) => (
  • β†’ {r}
  • ))}
)}
)}
)}
); }