Files
XCSDD/src/components/ApiDocViewer.tsx

75 lines
2.1 KiB
TypeScript

import { useState, useEffect, useCallback } from 'react'
import { DocTree } from './DocTree'
import { DocContent } from './DocContent'
import { parseMarkdown, buildFileTree } from '@/lib/parser'
import type { DocFile, ParsedDoc } from '@/lib/types'
import { docs } from '@/data/docs'
const DOCS_FILES: Record<string, string> = docs
export const ApiDocViewer = () => {
const [fileTree, setFileTree] = useState<DocFile[]>([])
const [selectedPath, setSelectedPath] = useState<string | undefined>()
const [currentDoc, setCurrentDoc] = useState<ParsedDoc | null>(null)
useEffect(() => {
const files = Object.keys(DOCS_FILES)
const basePath = '/docs'
const tree = buildFileTree(files, basePath)
setFileTree(tree)
if (files.length > 0) {
setSelectedPath(files[0])
}
}, [])
useEffect(() => {
if (selectedPath) {
const content = DOCS_FILES[selectedPath]
if (content) {
const parsed = parseMarkdown(content)
setCurrentDoc(parsed)
}
}
}, [selectedPath])
const handleSelect = useCallback((file: DocFile) => {
if (!file.isDir) {
setSelectedPath(file.relativePath)
}
}, [])
const handleReferenceClick = useCallback((ref: string) => {
const normalizedRef = ref.replace('.md', '')
const allFiles = Object.keys(DOCS_FILES).map(k => k.replace('/docs/', ''))
const match = allFiles.find(f => f.replace('.md', '') === normalizedRef)
if (match) {
setSelectedPath(match)
}
}, [])
return (
<div className="flex h-screen bg-[#1e1e1e]">
<aside className="w-64 bg-[#252526] border-r border-[#3c3c3c] flex flex-col">
<div className="p-3 border-b border-[#3c3c3c]">
<h2 className="text-sm font-semibold text-gray-200">API </h2>
</div>
<div className="flex-1 overflow-hidden">
<DocTree
files={fileTree}
selectedPath={selectedPath}
onSelect={handleSelect}
/>
</div>
</aside>
<main className="flex-1 overflow-hidden">
<DocContent
doc={currentDoc}
onReferenceClick={handleReferenceClick}
/>
</main>
</div>
)
}