'use client' import { useState, useEffect } from 'react' import { motion } from 'motion/react' import { Zap, Lightbulb, Trophy } from 'lucide-react' interface BridgeNote { noteId: string bridgeScore: number clustersConnected: number[] clusterNames?: string[] note?: { id: string title: string | null content: string } } interface BridgeSuggestion { clusterAId: number clusterBId: number clusterAName: string clusterBName: string suggestedTitle: string suggestedContent: string justification: string } interface BridgeNotesDashboardProps { onNoteClick?: (noteId: string) => void clusters: { id: number; name: string; color?: string }[] } export function BridgeNotesDashboard({ onNoteClick, clusters }: BridgeNotesDashboardProps) { const [bridgeNotes, setBridgeNotes] = useState([]) const [suggestions, setSuggestions] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { loadData() }, []) const loadData = async () => { setLoading(true) try { const bridgesRes = await fetch('/api/bridge-notes?details=true') if (bridgesRes.ok) { const bridgesData = await bridgesRes.json() setBridgeNotes(bridgesData.bridgeNotes || []) } const suggestionsRes = await fetch('/api/bridge-notes/suggestions') if (suggestionsRes.ok) { const suggestionsData = await suggestionsRes.json() setSuggestions(suggestionsData.suggestions || []) } } catch (error) { console.error('Error loading bridge data:', error) } finally { setLoading(false) } } const generateNewSuggestions = async () => { try { const res = await fetch('/api/bridge-notes/suggestions', { method: 'POST' }) if (res.ok) { const data = await res.json() setSuggestions(data.suggestions || []) } } catch (error) { console.error('Error generating suggestions:', error) } } const dismissSuggestion = async (clusterAId: number, clusterBId: number) => { try { await fetch('/api/bridge-notes', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clusterAId, clusterBId }) }) setSuggestions(prev => prev.filter( s => !(s.clusterAId === clusterAId && s.clusterBId === clusterBId) )) } catch (error) { console.error('Error dismissing suggestion:', error) } } if (loading) { return (
) } return (
{/* Stats Summary */}
Bridges
{bridgeNotes.length}
Suggestions
{suggestions.length}
{/* Bridge Notes Section */}

Powerful Bridge Notes

{bridgeNotes.map((bridge) => ( onNoteClick?.(bridge.noteId)} className="p-4 rounded-xl bg-white dark:bg-white/5 border border-border hover:border-ochre/40 transition-all cursor-pointer group" >

{bridge.note?.title || 'Untitled'}

Score: {(bridge.bridgeScore * 100).toFixed(0)}%
{bridge.clusterNames?.map((name, i) => { const cluster = clusters.find(c => c.name === name) return (
{name}
) })}
))} {bridgeNotes.length === 0 && (
No significant bridge notes found yet. Deepen your research to find new connections.
)}
{/* Connection Suggestions */}

Missing Links (AI Generated)

{suggestions.map((s, idx) => (
A
B
Bridging {s.clusterAName} & {s.clusterBName}

{s.suggestedTitle}

{s.suggestedContent}

{s.justification}
))} {suggestions.length === 0 && !loading && (

No connection suggestions yet

All your clusters may already be connected!

)}
) }