'use client'; import React from 'react'; import { useGraphStore } from '@/store/graph'; import { entityColor } from '@/lib/constants'; import { GitBranch, ChevronRight, FileText, Zap, Copy, Check, Info } from 'lucide-react'; export interface Hop { from: string; rel: string; to: string; doc?: string; chunk_text?: string; } interface AlternativePath { hops: Hop[]; explanation: string; } interface PathViewProps { hops: Hop[]; alternativePaths: AlternativePath[]; activeTab: number; onTabChange: (index: number) => void; explanation: string; entityA: string; entityB: string; copied: boolean; onCopy: () => void; onExplainPath?: (index: number) => void; explainingLoading?: boolean; } function NodeBadge({ name, isStart, isEnd }: { name: string; isStart?: boolean; isEnd?: boolean }) { const nodes = useGraphStore((s) => s.data.nodes); const foundNode = nodes.find(n => n.name === name || n.id === name); const type = foundNode ? foundNode.type : 'ENTITY'; const color = entityColor(type); const bg = `${color}14`; // ~8% opacity const border = `${color}4D`; // ~30% opacity return (
{type}
{name} {isStart && Start Node} {isEnd && End Node}
); } function RelArrow({ rel, doc }: { rel: string; doc?: string }) { return (
{/* Connector Line */}
{/* Relation Type Badge */} {rel.replace(/_/g, ' ')} {doc && ( {doc.replace(/\.[^.]+$/, '')} )}
); } function StepRow({ hop, index }: { hop: Hop; index: number }) { const [expanded, setExpanded] = React.useState(false); return (
{index + 1}
{hop.from} {hop.rel.replace(/_/g, ' ')} {hop.to}
{hop.doc && (
Source Document: {hop.doc}
)} {hop.chunk_text && ( )}
{expanded && hop.chunk_text && (

Verbatim Ingested Text Chunk

{hop.chunk_text}
)}
); } export function PathView({ hops, alternativePaths, activeTab, onTabChange, explanation, entityA, entityB, copied, onCopy, onExplainPath, explainingLoading, }: PathViewProps) { const pathsList = [ { hops, explanation }, ...alternativePaths ]; // Helper to generate a professional tab label indicating intermediate steps const getPathLabel = (pathHops: Hop[], index: number) => { if (pathHops.length === 0) return `Path ${index + 1}`; // Extract intermediate node names (endpoints of relationships except the last destination) const intermediates: string[] = []; for (let stepIdx = 0; stepIdx < pathHops.length - 1; stepIdx++) { intermediates.push(pathHops[stepIdx].to); } const prefix = index === 0 ? 'Primary Path' : `Alt Path ${index}`; if (intermediates.length > 0) { return `${prefix} via ${intermediates.join(', ')}`; } return `${prefix} (Direct)`; }; const currentPath = pathsList[activeTab]?.hops || []; const currentExplanation = pathsList[activeTab]?.explanation || ''; return (
{/* ── PATH TITLE BANNER ── */}
Reasoning Path Found {currentPath.length} hop{currentPath.length !== 1 ? 's' : ''} {alternativePaths.length > 0 && ( +{alternativePaths.length} alternative path{alternativePaths.length > 1 ? 's' : ''} )}
{/* ── STICKY PATH CONTROLLER ── */}
{/* ── PATH TABS (IF MULTIPLE PATHS EXIST) ── */} {pathsList.length > 1 && (
{pathsList.map((_, i) => { const isActive = activeTab === i; return ( ); })}
)} {/* ── ACTIVE PATH SUMMARY BREADCRUMB ── */}
Active Graph Pathway: {activeTab === 0 ? 'Primary Route' : `Alternative Route ${activeTab}`} Highlighted on Graph
{(() => { const nodesList: string[] = []; if (currentPath.length > 0) { nodesList.push(currentPath[0].from); for (const h of currentPath) { nodesList.push(h.to); } } return nodesList.map((n, idx) => ( {idx > 0 && } {n} )); })()}
{/* ── VISUAL CHAIN DIAGRAM ── */}

Interactive Visual Chain Flow

{currentPath.map((hop, i) => (
{i === currentPath.length - 1 && ( )}
))}
{/* ── STEP-BY-STEP DESCRIPTIVE ANNOTATION ── */}

Path Step Details

{currentPath.map((hop, i) => ( ))}
{/* ── AI CONCLUSION CARD ── */} {currentExplanation ? (

AI Reasoning Explanation ({activeTab === 0 ? 'Primary Path' : `Alt Path ${activeTab}`})

{currentExplanation}

Pathway loaded & visualized on graph Active
) : (

Generate Path-Specific Explanation

Generate a custom LLM summary explaining the connection path between {entityA} and {entityB} using this path's specific document chunks.

)}
); }