import { useState } from 'react' import { useComponentTreeLoader } from '@/hooks/use-component-tree-loader' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' import { toast } from 'sonner' import { Cube, TreeStructure, ArrowsClockwise, CheckCircle, Warning, Package, Stack, } from '@phosphor-icons/react' import componentTreeCopy from '@/data/component-tree-viewer.json' import { ComponentNode, ComponentTree } from '@/types/project' type ComponentTreeCategory = 'molecule' | 'organism' type ComponentTreeWithCategory = ComponentTree & { category?: ComponentTreeCategory } type ComponentTreeHeaderProps = { isLoaded: boolean isLoading: boolean totalTrees: number onReload: () => void } type ComponentTreeStatusProps = { error: Error | null } type ComponentTreeListProps = { trees: ComponentTreeWithCategory[] selectedTreeId: string | null onSelect: (id: string) => void variant: 'molecules' | 'organisms' | 'all' } type ComponentTreeDetailProps = { tree?: ComponentTree } const formatDate = (timestamp: number) => new Date(timestamp).toLocaleDateString() const getCategoryLabel = (category?: ComponentTreeCategory) => { if (!category) { return '' } return componentTreeCopy.categories[category] ?? category } export function ComponentTreeViewer() { const { isLoaded, isLoading, error, moleculeTrees, organismTrees, allTrees, reloadFromJSON, } = useComponentTreeLoader() const [selectedTreeId, setSelectedTreeId] = useState(null) const handleReload = async () => { try { await reloadFromJSON() toast.success(componentTreeCopy.toast.reloadSuccess) } catch (err) { toast.error(componentTreeCopy.toast.reloadError) } } const selectedTree = allTrees.find(tree => tree.id === selectedTreeId) return (
{componentTreeCopy.tabs.molecules} {moleculeTrees.length} {componentTreeCopy.tabs.organisms} {organismTrees.length} {componentTreeCopy.tabs.all} {allTrees.length}
) } function ComponentTreeHeader({ isLoaded, isLoading, totalTrees, onReload, }: ComponentTreeHeaderProps) { return (

{componentTreeCopy.header.title}

{componentTreeCopy.header.subtitle}

{isLoaded && ( {totalTrees} {componentTreeCopy.header.loadedLabel} )}
) } function ComponentTreeStatus({ error }: ComponentTreeStatusProps) { if (!error) { return null } return (

{componentTreeCopy.status.errorTitle}

{error.message}

) } function ComponentTreeList({ trees, selectedTreeId, onSelect, variant, }: ComponentTreeListProps) { return (
{trees.map(tree => { const categoryLabel = variant === 'all' ? getCategoryLabel(tree.category) : '' const treeIcon = variant === 'molecules' ? 'molecule' : variant === 'organisms' ? 'organism' : tree.category return ( onSelect(tree.id)} > {treeIcon === 'molecule' ? ( ) : ( )} {tree.name} {categoryLabel ? ( {categoryLabel} ) : null} {tree.description}
{tree.rootNodes.length} {componentTreeCopy.labels.rootNodes} {formatDate(tree.updatedAt)}
) })}
) } function ComponentTreeDetails({ tree }: ComponentTreeDetailProps) { if (!tree) { return (

{componentTreeCopy.status.selectPrompt}

) } return (

{tree.name}

{tree.description}

{tree.rootNodes.length} {componentTreeCopy.labels.rootNodes} {componentTreeCopy.labels.id}: {tree.id}

{componentTreeCopy.labels.structureTitle}

{tree.rootNodes.map(node => ( ))}
) } type ComponentTreeNodeProps = { node: ComponentNode depth?: number } function ComponentTreeNode({ node, depth = 0 }: ComponentTreeNodeProps) { return (
{node.name || node.type} {node.type}
{Object.keys(node.props).length > 0 && (
{componentTreeCopy.labels.props}: {Object.keys(node.props).length}
)}
{node.children.map(child => ( ))}
) }