diff --git a/components/InteractiveTerminal/InteractiveTerminal.tsx b/components/InteractiveTerminal/InteractiveTerminal.tsx new file mode 100644 index 0000000..23bf93f --- /dev/null +++ b/components/InteractiveTerminal/InteractiveTerminal.tsx @@ -0,0 +1,59 @@ +import React, { useEffect, useState } from 'react'; +import styles from '../../styles/InteractiveTerminal.module.css'; + +const InteractiveTerminal: React.FC = () => { + const [jsonData, setJsonData] = useState(null); + const [expandedNodes, setExpandedNodes] = useState>(new Set()); + + useEffect(() => { + fetch('https://raw.githubusercontent.com/cosmos/chain-registry/refs/heads/master/sei/chain.json') + .then((res) => res.json()) + .then((data) => setJsonData(data)) + .catch((err) => console.error('Failed to fetch JSON data:', err)); + }, []); + + const toggleNode = (path: string) => { + setExpandedNodes((prevNodes) => { + const newNodes = new Set(prevNodes); + if (newNodes.has(path)) { + newNodes.delete(path); + } else { + newNodes.add(path); + } + return newNodes; + }); + }; + + const renderNode = (key: string, value: any, path: string) => { + const isExpandable = typeof value === 'object' && value !== null; + const isOpen = expandedNodes.has(path); + const displayKey = key || 'root'; + + return ( +
+
isExpandable && toggleNode(path)}> + {isExpandable && (isOpen ? '▼' : '▶')} {displayKey} +
+ {isExpandable && isOpen && ( +
+ {Object.entries(value).map(([childKey, childValue]) => renderNode(childKey, childValue, `${path}.${childKey}`))} +
+ )} + {!isExpandable &&
{String(value)}
} +
+ ); + }; + + return ( +
+
+
+
+
+
+
{jsonData ? renderNode('', jsonData, 'root') :
Loading...
}
+
+ ); +}; + +export default InteractiveTerminal; diff --git a/components/InteractiveTerminal/index.ts b/components/InteractiveTerminal/index.ts new file mode 100644 index 0000000..2c9456b --- /dev/null +++ b/components/InteractiveTerminal/index.ts @@ -0,0 +1 @@ +export { default as InteractiveTerminal } from './InteractiveTerminal'; diff --git a/components/index.ts b/components/index.ts index 6d8b93b..4219720 100644 --- a/components/index.ts +++ b/components/index.ts @@ -15,3 +15,4 @@ export * from './Nfts'; export * from './VersionFetcher'; export * from './PropertyInfo'; export * from './EcosystemMap'; +export * from './InteractiveTerminal'; diff --git a/styles/InteractiveTerminal.module.css b/styles/InteractiveTerminal.module.css new file mode 100644 index 0000000..9d5b787 --- /dev/null +++ b/styles/InteractiveTerminal.module.css @@ -0,0 +1,53 @@ +.terminal { + background-color: #1e1e1e; + color: #00ff00; + border-radius: 8px; + padding: 16px; + font-family: 'Courier New', monospace; + width: 600px; + margin: 0 auto; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.header { + display: flex; + justify-content: flex-start; + padding-bottom: 8px; +} + +.circle { + width: 12px; + height: 12px; + border-radius: 50%; + margin-right: 8px; +} + +.body { + background-color: #1b1b1b; + border-radius: 4px; + padding: 8px; + overflow-y: auto; + max-height: 400px; +} + +.node { + margin-left: 16px; +} + +.nodeHeader { + cursor: pointer; + user-select: none; +} + +.nodeChildren { + margin-left: 16px; +} + +.leafNode { + margin-left: 32px; +} + +.loading { + text-align: center; + color: #d1d5db; +}