import { useEffect, useState, useCallback } from "react"; import { Link } from "react-router-dom"; import { fetchMemories, deleteMemoryApi, updateMemoryApi } from "../api/client.ts"; import type { QueryMemoriesResult } from "@fixonce/shared"; export function Dashboard() { const [stats, setStats] = useState<{ total: number; guidance: number; antiPattern: number; } | null>(null); const [flaggedResults, setFlaggedResults] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const loadData = useCallback(async () => { setLoading(true); setError(null); try { const [allResults, guidanceResults, antiPatternResults] = await Promise.all([ fetchMemories({ query: "", verbosity: "small", max_results: "1" }), fetchMemories({ query: "", memory_type: "guidance", verbosity: "small", max_results: "1" }), fetchMemories({ query: "", memory_type: "anti_pattern", verbosity: "small", max_results: "1" }), ]); setStats({ total: allResults.total_found, guidance: guidanceResults.total_found, antiPattern: antiPatternResults.total_found, }); const flagged = await fetchMemories({ query: "", verbosity: "medium", max_results: "20", }); setFlaggedResults(flagged); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load dashboard data"); } finally { setLoading(false); } }, []); useEffect(() => { void loadData(); }, [loadData]); async function handleDisable(id: string) { try { await updateMemoryApi(id, { enabled: false }); void loadData(); } catch (err) { setError(err instanceof Error ? err.message : "Failed to disable memory"); } } async function handleDelete(id: string) { if (!window.confirm("Permanently delete this memory? This cannot be undone.")) { return; } try { await deleteMemoryApi(id); void loadData(); } catch (err) { setError(err instanceof Error ? err.message : "Failed to delete memory"); } } if (loading) { return

Loading dashboard...

; } return (

Dashboard

{error &&

{error}

} {stats && (
)}

Recent Memories

{flaggedResults && flaggedResults.results.length > 0 ? ( {flaggedResults.results.map((m) => ( ))}
Title Type Score Actions
{m.title} {m.memory_type} {m.relevancy_score.toFixed(2)}
) : (

No memories found.

)}
); } function StatCard({ label, value }: { label: string; value: number }) { return (
{value}
{label}
); } const thStyle: React.CSSProperties = { textAlign: "left", padding: "0.5rem", borderBottom: "2px solid #ddd", }; const tdStyle: React.CSSProperties = { padding: "0.5rem", borderBottom: "1px solid #eee", }; const btnStyle: React.CSSProperties = { background: "none", border: "1px solid #ccc", borderRadius: "3px", padding: "0.25rem 0.5rem", cursor: "pointer", marginRight: "0.25rem", fontSize: "0.8rem", };