import { useState, useEffect, useCallback } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import {
Dna, Brain, DollarSign, Scale, Hash, Shield, Film, Image,
RefreshCw, Lock, Unlock, Loader2, AlertTriangle, Check, Play,
FileText, TrendingUp, Activity, Eye,
} from 'lucide-react'
const API_BASE = ''
const GLYPHS = {
dna: 'โ', ml: 'โก', valuation: '$', profile: 'ยง', kpi: '#',
password: '๐', gif: 'โ', video: 'โถ', reindex: 'โป',
}
export default function FileIntelligence({ fileId, onBack }) {
const [files, setFiles] = useState([])
const [selectedId, setSelectedId] = useState(fileId)
const [activeTab, setActiveTab] = useState('dna')
const [loading, setLoading] = useState(false)
useEffect(() => {
fetch(`${API_BASE}/files`).then(r => r.json()).then(d => {
setFiles(d.files || [])
if (!selectedId && d.files?.length > 0) setSelectedId(d.files[0].file_id)
}).catch(() => {})
}, [])
useEffect(() => { if (fileId) setSelectedId(fileId) }, [fileId])
const tabs = [
{ id: 'dna', label: 'DNA', icon: Dna },
{ id: 'ml', label: 'ML', icon: Brain },
{ id: 'valuation', label: 'Valuation', icon: DollarSign },
{ id: 'profile', label: 'Profile', icon: Scale },
{ id: 'kpi', label: 'KPIs', icon: Hash },
{ id: 'password', label: 'Password', icon: Shield },
{ id: 'gif', label: 'KPI GIF', icon: Image },
{ id: 'video', label: 'Video', icon: Film },
{ id: 'reindex', label: 'Reindex', icon: RefreshCw },
]
return (
{/* File selector + back */}
{onBack && (
)}
{files.map(f => (
))}
{/* Tabs */}
{tabs.map(tab => (
))}
{selectedId && activeTab === 'dna' && }
{selectedId && activeTab === 'ml' && }
{selectedId && activeTab === 'valuation' && }
{selectedId && activeTab === 'profile' && }
{selectedId && activeTab === 'kpi' && }
{selectedId && activeTab === 'password' && }
{selectedId && activeTab === 'gif' && }
{selectedId && activeTab === 'video' && }
{selectedId && activeTab === 'reindex' && }
{!selectedId && (
No file selected.
)}
)
}
// โโโ DNA Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function DNAPanel({ fileId }) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch(`${API_BASE}/dna/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
}, [fileId])
if (loading) return
if (data?.error) return
const genes = data.genes || {}
const complexity = data.complexity_score || 0
return (
{GLYPHS.dna}
Structural DNA
{data.genome_size || 0} bytes
Genes (10 structural metrics)
{Object.entries(genes).map(([k, v]) => (
{k.replace(/_/g, ' ')}
{typeof v === 'number' ? v.toLocaleString() : String(v).slice(0, 20)}
))}
)
}
// โโโ ML Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function MLPanel({ fileId }) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch(`${API_BASE}/ml/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
}, [fileId])
if (loading) return
if (data?.error) return
const ml = data.ml || {}
if (!ml.available) return (
ML unavailable โ {ml.error || 'unknown error'}
)
return (
{GLYPHS.ml}
ML Insights
{ml.engine || 'sklearn'}
{/* TF-IDF */}
{ml.tfidf_top_terms?.length > 0 && (
TF-IDF Top Terms
{ml.tfidf_top_terms.map((t, i) => (
{t.term} {t.score}
))}
)}
{/* Topics */}
{ml.topics?.length > 0 && (
Topics
{ml.topics.map((t, i) => (
T{t.topic_id}
{t.keywords?.map((kw, j) => (
{kw}
))}
{t.chunk_count} chunks ยท {t.strength}
))}
)}
{/* Clusters */}
{ml.clusters && Object.keys(ml.clusters).length > 0 && (
Clusters
{Object.entries(ml.clusters).map(([k, c]) => (
{k}
{c.size} chunks
{c.centroid_terms?.map((t, i) => (
{t}
))}
))}
)}
{/* Anomalies */}
{ml.anomalies?.length > 0 && (
Anomalies ({ml.anomalies.length})
{ml.anomalies.map((a, i) => (
Chunk #{a.chunk_idx}
{a.reason}
))}
)}
{/* Inferred KPIs */}
{ml.inferred_kpis?.length > 0 && (
Inferred KPIs
{ml.inferred_kpis.map((k, i) => (
{k.name}
{k.value}
{k.method}
))}
)}
{/* LLM Extrapolation */}
{ml.llm_extrapolation && (
LLM Extrapolation
{ml.llm_extrapolation.inferred_purpose &&
Purpose: {ml.llm_extrapolation.inferred_purpose}
}
{ml.llm_extrapolation.hidden_value &&
Hidden Value: {ml.llm_extrapolation.hidden_value}
}
{ml.llm_extrapolation.counterparty_risk &&
Risk: {ml.llm_extrapolation.counterparty_risk}
}
{ml.llm_extrapolation.monetization_vector &&
Monetization: {ml.llm_extrapolation.monetization_vector}
}
)}
)
}
// โโโ Valuation Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function ValuationPanel({ fileId }) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch(`${API_BASE}/valuation/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
}, [fileId])
if (loading) return
if (data?.error) return
const v = data.valuation || {}
return (
{GLYPHS.valuation}
Valuation
Prod Readiness
{v.production_readiness?.grade || 'F'}
{v.production_readiness?.score || 0}/100
{v.production_readiness?.distance_to_prod || 'โ'}
File Type
{v.build_cost?.breakdown?.file_type || 'โ'}
Rate: ${v.build_cost?.breakdown?.rate_per_loc || 0}/LOC
Difficulty
{v.replacement_cost?.difficulty || 'โ'}
{v.replacement_cost?.time_to_rebuild?.days || 0} days to rebuild
{v.production_readiness?.blocking_issues?.length > 0 && (
{v.production_readiness.blocking_issues.map((issue, i) => (
โ {issue}
))}
)}
{v.depreciation?.signals?.length > 0 && (
Depreciation Signals
{v.depreciation.signals.map((s, i) => (
{s}
))}
)}
)
}
// โโโ Profile Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function ProfilePanel({ fileId }) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch(`${API_BASE}/profile/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
}, [fileId])
if (loading) return
if (data?.error) return
const p = data.profile || {}
return (
{GLYPHS.profile}
Semantic Profile
{/* Origin */}
Origin
{p.origin?.primary || 'unknown'}
{p.origin?.detected?.map((o, i) => (
{o.type} ({Math.round(o.confidence * 100)}%)
))}
{/* Accounting + Finance */}
Accounting
{p.accounting?.standards_detected?.length > 0 ? (
{p.accounting.standards_detected.map(s => (
{s}
))}
) :
No standards detected
}
{p.accounting?.concepts_found && Object.keys(p.accounting.concepts_found).length > 0 && (
{Object.entries(p.accounting.concepts_found).map(([k, v]) => (
{k} ร{v}
))}
)}
Finance
{p.finance?.metrics_detected && Object.keys(p.finance.metrics_detected).length > 0 ? (
{Object.entries(p.finance.metrics_detected).map(([k, v]) => (
{k} ร{v}
))}
) :
No metrics detected
}
{/* Collateral + Liquidity + Risk */}
Collateral
{p.collateral?.grade || 'F'}
{p.collateral?.score || 0}/100
Liquidity
{p.liquidity?.grade || 'F'}
{p.liquidity?.score || 0}/100
{p.liquidity?.time_to_liquidate || 'โ'}
Risk Level
{p.risk?.level || 'unknown'}
{p.risk?.score || 0}/100
)
}
// โโโ KPI Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function KPIPanel({ fileId }) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch(`${API_BASE}/kpi/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
}, [fileId])
if (loading) return
if (data?.error) return
const cats = data.by_category || {}
return (
{GLYPHS.kpi}
KPIs ({data.total_kpis || 0})
{Object.keys(cats).length === 0 ? (
No KPIs extracted
) : (
{Object.entries(cats).map(([cat, kpis]) => (
{cat} ({kpis.length})
{kpis.map((k, i) => (
{k.name}
{k.value}
L{k.line}
{Math.round((k.confidence || 0) * 100)}%
))}
))}
)}
)
}
// โโโ Password Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function PasswordPanel({ fileId }) {
const [status, setStatus] = useState(null)
const [password, setPassword] = useState('')
const [verifyPassword, setVerifyPassword] = useState('')
const [result, setResult] = useState(null)
const [verifyResult, setVerifyResult] = useState(null)
const [loading, setLoading] = useState(false)
useEffect(() => {
fetch(`${API_BASE}/password/${fileId}/status`).then(r => r.json()).then(d => setStatus(d)).catch(() => setStatus({ error: 'Failed' }))
}, [fileId])
const setPassword_ = async () => {
if (!password) return
setLoading(true); setResult(null)
try {
const res = await fetch(`${API_BASE}/password/${fileId}`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password })
})
const d = await res.json()
setResult(d)
if (!d.error) { setStatus({ has_password: true }); setPassword('') }
} catch (e) { setResult({ error: e.message }) }
finally { setLoading(false) }
}
const verifyPwd = async () => {
if (!verifyPassword) return
setLoading(true); setVerifyResult(null)
try {
const res = await fetch(`${API_BASE}/password/${fileId}/verify`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password: verifyPassword })
})
const d = await res.json()
setVerifyResult(d)
} catch (e) { setVerifyResult({ error: e.message }) }
finally { setLoading(false) }
}
const hasPwd = status?.has_password
return (
{GLYPHS.password}
{hasPwd ? : }
Password Protection
{hasPwd ? 'โ PROTECTED' : 'โ UNPROTECTED'}
{/* Set password */}
{hasPwd ? 'Update Password' : 'Set Password'}
setPassword(e.target.value)}
onKeyDown={e => e.key === 'Enter' && setPassword_()}
placeholder="Enter password..."
className="flex-1 px-3 py-2 rounded-xl glass text-xs font-mono text-text placeholder:text-secondary/30 outline-none focus:glass-orange"
/>
{result?.error &&
โ {result.error}
}
{result?.status === 'set' &&
โ Password set successfully
}
{/* Verify password */}
{hasPwd && (
Verify Password
setVerifyPassword(e.target.value)}
onKeyDown={e => e.key === 'Enter' && verifyPwd()}
placeholder="Enter password to verify..."
className="flex-1 px-3 py-2 rounded-xl glass text-xs font-mono text-text placeholder:text-secondary/30 outline-none focus:glass-orange"
/>
{verifyResult?.verified &&
Verified โ access granted
}
{verifyResult?.verified === false &&
}
{verifyResult?.error &&
โ {verifyResult.error}
}
)}
{/* Hash info */}
{status?.hash_prefix && (
Hash
{status.hash_prefix}... ยท PBKDF2 ยท {status.iterations || 100000} iterations
)}
)
}
// โโโ GIF Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function GIFPanel({ fileId }) {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [gifUrl, setGifUrl] = useState(null)
const generate = async () => {
setLoading(true); setError(null); setGifUrl(null)
try {
const res = await fetch(`${API_BASE}/kpi/${fileId}/gif`)
if (!res.ok) {
const d = await res.json().catch(() => ({}))
setError(d.error || `HTTP ${res.status}`)
} else {
const blob = await res.blob()
setGifUrl(URL.createObjectURL(blob))
}
} catch (e) { setError(e.message) }
finally { setLoading(false) }
}
return (
{GLYPHS.gif}
KPI Animated GIF
{error &&
โ {error}
}
{gifUrl && (
)}
)
}
// โโโ Video Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function VideoPanel({ fileId }) {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const [videoUrl, setVideoUrl] = useState(null)
const generate = async () => {
setLoading(true); setError(null); setVideoUrl(null)
try {
const res = await fetch(`${API_BASE}/video/${fileId}`)
if (!res.ok) {
const d = await res.json().catch(() => ({}))
setError(d.error || `HTTP ${res.status}`)
} else {
const blob = await res.blob()
setVideoUrl(URL.createObjectURL(blob))
}
} catch (e) { setError(e.message) }
finally { setLoading(false) }
}
return (
{GLYPHS.video}
Video Dossier
{error &&
โ {error}
}
{videoUrl && (
)}
)
}
// โโโ Reindex Panel โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function ReindexPanel({ fileId }) {
const [loading, setLoading] = useState(false)
const [result, setResult] = useState(null)
const [error, setError] = useState(null)
const reindex = async () => {
setLoading(true); setResult(null); setError(null)
try {
const res = await fetch(`${API_BASE}/reindex/${fileId}`, { method: 'POST' })
const d = await res.json()
if (d.error) setError(d.error)
else setResult(d)
} catch (e) { setError(e.message) }
finally { setLoading(false) }
}
return (
{GLYPHS.reindex}
Re-Index File
Rebuilds the file index with the latest extraction algorithms. Use after backend updates to refresh DNA, KPIs, and all analysis layers.
{error &&
โ {error}
}
{result && (
Result
{result.old_file_id !== result.new_file_id && (
โ File ID changed: {result.old_file_id} โ {result.new_file_id}
)}
)}
)
}
// โโโ Helper components โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function LoadingSpinner({ label }) {
return (
)
}
function ErrorBox({ msg }) {
return (
)
}
function StatBox({ label, value, mono }) {
return (
)
}
function ValueBox({ label, value, glyph, sub }) {
const formatted = typeof value === 'number' && value > 0 ? `$${value.toLocaleString()}` : value ? `$${value}` : 'โ'
return (
{glyph}
{label}
{formatted}
{sub &&
{sub}
}
)
}