({
mapped,
unmapped,
activeCategories,
onToggleCategory,
onFlyTo,
selectedMarket,
onSelectMarket,
selectedCountry,
activeTab,
onTabChange,
timeRange,
onTimeRangeChange,
autoRefresh,
onToggleAutoRefresh,
loading,
}: TabbedPanelProps)
| 38 | const NEW_THRESHOLD_MS = 6 * 60 * 60 * 1000; |
| 39 | |
| 40 | export default function TabbedPanel({ |
| 41 | mapped, |
| 42 | unmapped, |
| 43 | activeCategories, |
| 44 | onToggleCategory, |
| 45 | onFlyTo, |
| 46 | selectedMarket, |
| 47 | onSelectMarket, |
| 48 | selectedCountry, |
| 49 | activeTab, |
| 50 | onTabChange, |
| 51 | timeRange, |
| 52 | onTimeRangeChange, |
| 53 | autoRefresh, |
| 54 | onToggleAutoRefresh, |
| 55 | loading, |
| 56 | }: TabbedPanelProps) { |
| 57 | const handleMarketClick = (m: ProcessedMarket) => { |
| 58 | onSelectMarket(m); |
| 59 | onTabChange("detail"); |
| 60 | if (m.coords) onFlyTo(m.coords, m.id); |
| 61 | }; |
| 62 | |
| 63 | // Compute related markets for the detail panel |
| 64 | const relatedMarkets = useMemo(() => { |
| 65 | if (!selectedMarket) return []; |
| 66 | const all = [...mapped, ...unmapped]; |
| 67 | return all |
| 68 | .filter( |
| 69 | (m) => |
| 70 | m.id !== selectedMarket.id && |
| 71 | (m.category === selectedMarket.category || |
| 72 | (selectedMarket.location && m.location === selectedMarket.location)) |
| 73 | ) |
| 74 | .sort((a, b) => (b.volume24h || 0) - (a.volume24h || 0)) |
| 75 | .slice(0, 5); |
| 76 | }, [selectedMarket, mapped, unmapped]); |
| 77 | |
| 78 | return ( |
| 79 | <aside className="w-[340px] bg-[#0a0a0a] border-l border-[#1e1e1e] flex flex-col shrink-0 hidden md:flex"> |
| 80 | {/* Tab bar */} |
| 81 | <div className="flex border-b border-[#1e1e1e] shrink-0"> |
| 82 | {TABS.map((tab) => ( |
| 83 | <button |
| 84 | key={tab.id} |
| 85 | onClick={() => onTabChange(tab.id)} |
| 86 | className={`flex-1 py-1.5 text-[10px] font-mono tracking-wide transition-colors ${ |
| 87 | activeTab === tab.id |
| 88 | ? "text-[#e8e8e8] bg-[#141414] border-b border-[#e8e8e8]" |
| 89 | : "text-[#777] hover:text-[#a0a0a0] hover:bg-[#0e0e0e]" |
| 90 | }`} |
| 91 | > |
| 92 | {tab.label} |
| 93 | </button> |
| 94 | ))} |
| 95 | </div> |
| 96 | |
| 97 | {/* Tab content with fade transition */} |
nothing calls this directly
no outgoing calls
no test coverage detected