import { useEffect, useState, useCallback } from 'react'
import { useParams } from 'react-router-dom'
import { apiFetch } from '@core/lib/api'
import { useAppPath } from '@core/hooks/useAppPath'
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
import { Button } from '@core/components/ui/button'
import { Badge } from '@core/components/ui/badge'
import { Skeleton } from '@core/components/ui/skeleton'
import { Progress } from '@core/components/ui/progress'
import {
CheckCircle2,
XCircle,
AlertTriangle,
Clock,
ChevronRight,
RefreshCw,
FileCode2,
Layers,
Zap,
Sparkles,
GitGraph,
Hash,
DollarSign,
Bot,
Search,
Play,
Settings2,
} from 'lucide-react'
// ─── TYPES ────────────────────────────────────────────────────────────────────
interface ProjectStats {
file_count: number
chunk_count: number
proposal_count: number
approved_count: number
pending_review_count: number
total_ingestion_cost_usd: number
last_ingested_at: string | null
}
interface EmbedStatus {
total_chunks: number
embedded_chunks: number
coverage_pct: number
unembedded_chunks: number
}
interface DocStatus {
total_chunks: number
documented_count: number
undocumented_count: number
ai_generated_count: number
human_verified_count: number
coverage_pct: number
}
interface CallmapStatus {
import_links: number
call_links: number
export_links: number
total_links: number
tested_by_links?: number
}
interface ConfigStatus {
config_items: number
configures_links: number
}
interface DashboardData {
project: { id: string; title: string; data: ProjectStats } | null
embed: EmbedStatus | null
doc: DocStatus | null
callmap: CallmapStatus | null
config: ConfigStatus | null
}
// ─── PIPELINE PASS STATUS CARD ────────────────────────────────────────────────
function PassCard({
number,
label,
icon: Icon,
description,
status,
metric,
href,
}: {
number: string
label: string
icon: React.ElementType
description: string
status: 'complete' | 'partial' | 'empty' | 'unknown'
metric: string
href?: string
}) {
const statusConfig = {
complete: { color: 'text-green-600', bg: 'bg-green-50 border-green-200', dot: 'bg-green-500', icon: CheckCircle2 },
partial: { color: 'text-amber-600', bg: 'bg-amber-50 border-amber-200', dot: 'bg-amber-500', icon: AlertTriangle },
empty: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
unknown: { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200', dot: 'bg-slate-300', icon: Clock },
}[status]
const StatusIcon = statusConfig.icon
return (
Pass {number}
{label}
{description}
{metric}
{href && (
)}
)
}
// ─── STAT TILE ────────────────────────────────────────────────────────────────
function StatTile({
label,
value,
sub,
icon: Icon,
accent = false,
}: {
label: string
value: string | number
sub?: string
icon: React.ElementType
accent?: boolean
}) {
return (
{value}
{label}
{sub &&
{sub}
}
)
}
// ─── COVERAGE BAR ─────────────────────────────────────────────────────────────
function CoverageBar({ label, pct, color = 'bg-indigo-500' }: { label: string; pct: number; color?: string }) {
return (
)
}
// ─── DRIFT ALERT CARD ─────────────────────────────────────────────────────────
function DriftAlertCard({ projectId, appPath }: { projectId: string; appPath: (p: string) => string }) {
const [driftChunks, setDriftChunks] = useState(null)
const [checking, setChecking] = useState(false)
const checkDrift = async () => {
setChecking(true)
try {
// Get all chunks with stored hashes for this project
const res = await apiFetch(`/api/admin-data?action=list&entity=items&type_slug=cil_chunk&limit=200`)
const data = await res.json()
const chunks = (data?.data || data || []).filter(
(c: any) => c.data?.project_id === projectId && c.data?.stored_hash
)
if (!chunks.length) { setDriftChunks([]); return }
// Batch validate — send all at once
const validateRes = await apiFetch('/api/custom_cil-validate?action=validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chunks: chunks.slice(0, 50).map((c: any) => ({
chunk_id: c.id,
chunk_name: c.data?.chunk_name || '',
content: c.data?.code_content || '',
})),
}),
})
const vData = await validateRes.json()
const results = vData?.results || vData?.data?.results || []
setDriftChunks(results.filter((r: any) => r.status === 'drift_detected'))
} finally {
setChecking(false)
}
}
return (
Hash Drift
{driftChunks === null && (
Click "Check Now" to validate all stored hashes against current code_content.
)}
{driftChunks?.length === 0 && (
All hashes current
)}
{driftChunks && driftChunks.length > 0 && (
{driftChunks.length} chunk{driftChunks.length !== 1 ? 's' : ''} with drift
{driftChunks.slice(0, 5).map((r: any) => (
{r.chunk_name}
))}
{driftChunks.length > 5 && (
…and {driftChunks.length - 5} more
)}
)}
)
}
// ─── MAIN PAGE ────────────────────────────────────────────────────────────────
export default function CILDashboardPage() {
const { id: projectId } = useParams<{ id: string }>()
const appPath = useAppPath()
const [data, setData] = useState({ project: null, embed: null, doc: null, callmap: null, config: null })
const [loading, setLoading] = useState(true)
const load = useCallback(async () => {
if (!projectId) return
setLoading(true)
try {
const [projectRes, embedRes, docRes, callmapRes, configRes] = await Promise.allSettled([
apiFetch(`/api/custom_cil-project?action=get&id=${projectId}`).then(r => r.json()),
apiFetch(`/api/custom_cil-embeddings?action=status&project_id=${projectId}`).then(r => r.json()),
apiFetch(`/api/custom_cil-doc?action=gap_report&project_id=${projectId}`).then(r => r.json()),
apiFetch(`/api/custom_cil-callmap?action=status&project_id=${projectId}`).then(r => r.json()),
apiFetch(`/api/custom_cil-config?action=status&project_id=${projectId}`).then(r => r.json()),
])
setData({
project: projectRes.status === 'fulfilled' ? (projectRes.value?.project || projectRes.value?.data?.project) : null,
embed: embedRes.status === 'fulfilled' ? (embedRes.value?.data || embedRes.value) : null,
doc: docRes.status === 'fulfilled' ? (docRes.value?.data || docRes.value) : null,
callmap: callmapRes.status === 'fulfilled' ? (callmapRes.value?.data || callmapRes.value) : null,
config: configRes.status === 'fulfilled' ? (configRes.value?.data || configRes.value) : null,
})
} finally {
setLoading(false)
}
}, [projectId])
useEffect(() => { load() }, [load])
if (loading) {
return (
{Array.from({ length: 4 }).map((_, i) => )}
{Array.from({ length: 4 }).map((_, i) => )}
)
}
const project = data.project
const stats: ProjectStats = project?.data || { file_count: 0, chunk_count: 0, proposal_count: 0, approved_count: 0, pending_review_count: 0, total_ingestion_cost_usd: 0, last_ingested_at: null }
const embed = data.embed || { total_chunks: 0, embedded_chunks: 0, coverage_pct: 0, unembedded_chunks: 0 }
const doc = data.doc || { total_chunks: 0, documented_count: 0, undocumented_count: 0, ai_generated_count: 0, human_verified_count: 0, coverage_pct: 0 }
const callmap = data.callmap || { import_links: 0, call_links: 0, export_links: 0, total_links: 0, tested_by_links: 0 }
const config = data.config || { config_items: 0, configures_links: 0 }
const lastIngested = stats.last_ingested_at
? new Date(stats.last_ingested_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
: 'Never'
// Determine pipeline pass status
const pass1Status = stats.file_count > 0 ? 'complete' : 'empty'
const pass2Status = stats.chunk_count > 0 ? 'complete' : (stats.file_count > 0 ? 'partial' : 'empty')
const pass3Status = embed.coverage_pct === 100 ? 'complete' : (embed.embedded_chunks > 0 ? 'partial' : 'empty') as any
const pass4Status = doc.coverage_pct === 100 ? 'complete' : (doc.documented_count > 0 ? 'partial' : 'empty') as any
const pass4bStatus = callmap.total_links > 0 ? 'complete' : 'empty' as any
const pass5Status = config.config_items > 0 ? (config.configures_links > 0 ? 'complete' : 'partial') : 'empty' as any
return (
{/* Breadcrumb */}
{/* Header */}
{project?.title || 'Project Dashboard'}
Last ingested: {lastIngested}
{/* Top stats */}
{/* Coverage bars */}
Coverage
{doc.ai_generated_count}
AI Generated
{doc.human_verified_count}
Human Verified
{doc.undocumented_count}
Undocumented
{/* Pipeline passes */}
{/* Link counts + drift check */}
{/* Graph stats */}
Graph Links
{[
{ label: 'Import links (file→file)', value: callmap.import_links },
{ label: 'Call links (chunk→chunk)', value: callmap.call_links },
{ label: 'Export links', value: callmap.export_links },
{ label: 'Tested-by links', value: callmap.tested_by_links ?? 0 },
].map(item => (
{item.label}
{item.value.toLocaleString()}
))}
{/* Drift check */}
{/* Quick actions */}
)
}