'use client'; import { useState, useEffect, useCallback } from 'react'; import TreeNode from './TreeNode'; import { taxonomy, getDomainSubcodeCount, getSubcodeCount } from '@/lib/taxonomy/data'; import type { SelectedSubcode } from '@/lib/taxonomy/types'; interface TaxonomyTreeProps { searchQuery: string; searchResults: { domains: string[]; categories: string[]; subcodes: string[]; }; selectedSubcode: SelectedSubcode | null; onSelectSubcode: (subcode: SelectedSubcode | null) => void; } export default function TaxonomyTree({ searchQuery, searchResults, selectedSubcode, onSelectSubcode, }: TaxonomyTreeProps) { const [expandedDomains, setExpandedDomains] = useState>(new Set()); const [expandedCategories, setExpandedCategories] = useState>(new Set()); // Auto-expand nodes when search results change useEffect(() => { if (searchQuery) { const domainsToExpand = new Set(); const categoriesToExpand = new Set(); // Expand domains that have matches searchResults.domains.forEach((d) => domainsToExpand.add(d)); // Expand parent domains for matched categories searchResults.categories.forEach((c) => { domainsToExpand.add(c[0]); categoriesToExpand.add(c); }); // Expand parent domains and categories for matched subcodes searchResults.subcodes.forEach((s) => { const domainKey = s[0]; const categoryKey = s.slice(0, 2); domainsToExpand.add(domainKey); categoriesToExpand.add(categoryKey); }); setExpandedDomains(domainsToExpand); setExpandedCategories(categoriesToExpand); } }, [searchQuery, searchResults]); const toggleDomain = useCallback((domainKey: string) => { setExpandedDomains((prev) => { const next = new Set(prev); if (next.has(domainKey)) { next.delete(domainKey); } else { next.add(domainKey); } return next; }); }, []); const toggleCategory = useCallback((categoryKey: string) => { setExpandedCategories((prev) => { const next = new Set(prev); if (next.has(categoryKey)) { next.delete(categoryKey); } else { next.add(categoryKey); } return next; }); }, []); const handleSelectSubcode = ( subcodeKey: string, domainKey: string, domainName: string, categoryKey: string, categoryName: string, subcode: SelectedSubcode['subcode'] ) => { onSelectSubcode({ code: subcodeKey, domainKey, domainName, categoryKey, categoryName, subcode, }); }; const isSubcodeSelected = (subcodeKey: string) => { return selectedSubcode?.code === subcodeKey; }; const isSearchMatch = (key: string) => { if (!searchQuery) return false; return ( searchResults.domains.includes(key) || searchResults.categories.includes(key) || searchResults.subcodes.includes(key) ); }; // Filter to show only matches when searching const shouldShowDomain = (domainKey: string) => { if (!searchQuery) return true; // Show domain if it matches or any of its children match if (searchResults.domains.includes(domainKey)) return true; if (searchResults.categories.some((c) => c.startsWith(domainKey))) return true; if (searchResults.subcodes.some((s) => s.startsWith(domainKey))) return true; return false; }; const shouldShowCategory = (categoryKey: string) => { if (!searchQuery) return true; if (searchResults.categories.includes(categoryKey)) return true; if (searchResults.subcodes.some((s) => s.startsWith(categoryKey))) return true; return false; }; const shouldShowSubcode = (subcodeKey: string) => { if (!searchQuery) return true; return searchResults.subcodes.includes(subcodeKey); }; return (
{Object.entries(taxonomy.domains).map(([domainKey, domain]) => { if (!shouldShowDomain(domainKey)) return null; return ( toggleDomain(domainKey)} searchMatch={isSearchMatch(domainKey)} > {Object.entries(domain.categories).map(([categoryKey, category]) => { if (!shouldShowCategory(categoryKey)) return null; return ( toggleCategory(categoryKey)} searchMatch={isSearchMatch(categoryKey)} > {Object.entries(category.subcodes).map(([subcodeKey, subcode]) => { if (!shouldShowSubcode(subcodeKey)) return null; return ( handleSelectSubcode( subcodeKey, domainKey, domain.name, categoryKey, category.name, subcode ) } searchMatch={isSearchMatch(subcodeKey)} /> ); })} ); })} ); })}
); }