"use client" import { memo, useMemo } from "react" import { cn } from "@lib/utils" import { dmSansClassName } from "@/lib/fonts" import { Expand } from "lucide-react" import { SuperLoader } from "@/components/superloader" import { useGraphApi } from "./hooks/use-graph-api" import { useViewMode } from "@/lib/view-mode-context" export interface GraphCardProps { containerTags?: string[] width?: number height?: number className?: string } // Simple seeded random for deterministic node positions function seededRandom(seed: number) { let s = seed return () => { s = (s * 16807 + 0) % 2147483647 return s / 2147483647 } } export function StaticGraphPreview({ documentCount, memoryCount, width, height, }: { documentCount: number memoryCount: number width: number height: number }) { const nodes = useMemo(() => { const rand = seededRandom(42) const count = Math.min(documentCount + memoryCount, 30) const docCount = Math.min(documentCount, 12) const result: { x: number y: number r: number color: string opacity: number }[] = [] const pad = 20 for (let i = 0; i < count; i++) { const isDoc = i < docCount result.push({ x: pad + rand() * (width - pad * 2), y: pad + rand() * (height - pad * 2), r: isDoc ? 4 + rand() * 3 : 2 + rand() * 2, color: isDoc ? "#4BA0FA" : "#36FDFD", opacity: 0.4 + rand() * 0.4, }) } return result }, [documentCount, memoryCount, width, height]) const edges = useMemo(() => { if (nodes.length < 2) return [] const rand = seededRandom(123) const result: { x1: number; y1: number; x2: number; y2: number }[] = [] const edgeCount = Math.min(nodes.length - 1, 20) for (let i = 0; i < edgeCount; i++) { const a = Math.floor(rand() * nodes.length) let b = Math.floor(rand() * nodes.length) if (b === a) b = (a + 1) % nodes.length result.push({ x1: nodes[a]?.x, y1: nodes[a]?.y, x2: nodes[b]?.x, y2: nodes[b]?.y, }) } return result }, [nodes]) return ( {edges.map((e, i) => ( ))} {nodes.map((n, i) => ( ))} ) } export const GraphCard = memo( ({ containerTags, width = 216, height = 220, className }) => { const { setViewMode } = useViewMode() const { documents, isLoading, error } = useGraphApi({ containerTags, enabled: true, }) if (error) { return ( Failed to load graph ) } const documentCount = documents.length const memoryCount = documents.reduce((sum, d) => sum + d.memories.length, 0) return ( setViewMode("graph")} className={cn( "bg-[#0B1017] border border-[rgba(255,255,255,0.05)] rounded-[18px] p-3 flex flex-col cursor-pointer transition-all hover:border-[rgba(255,255,255,0.1)] hover:bg-[#0f1419] group relative overflow-hidden", dmSansClassName(), className, )} style={{ width, height }} > {isLoading ? ( ) : documentCount > 0 || memoryCount > 0 ? ( ) : ( No documents yet )} {documentCount} docs {memoryCount} memories View graph ) }, ) GraphCard.displayName = "GraphCard"
Failed to load graph
No documents yet