47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
import { useState } from 'react';
|
|
import FileExplorer from './components/FileExplorer';
|
|
import DocumentEditor from './components/DocumentEditor';
|
|
import SearchBar from './components/SearchBar';
|
|
import SearchResults from './components/SearchResults';
|
|
import UploadButton from './components/UploadButton';
|
|
import type { SearchResult, UploadDocumentResponse } from './api/client';
|
|
|
|
export default function App() {
|
|
const [selectedKey, setSelectedKey] = useState<string | null>(null);
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
|
|
|
|
function handleJumpToResult(key: string) {
|
|
setSelectedKey(key);
|
|
setSearchQuery('');
|
|
setSearchResults([]);
|
|
}
|
|
|
|
function handleUploaded(result: UploadDocumentResponse) {
|
|
setSelectedKey(result.key);
|
|
}
|
|
|
|
return (
|
|
<div className="app">
|
|
<div className="topbar">
|
|
<h1>DocHub</h1>
|
|
<SearchBar onQueryChange={setSearchQuery} onResults={setSearchResults} />
|
|
<UploadButton path="" onUploaded={handleUploaded} />
|
|
</div>
|
|
<div className="body">
|
|
<FileExplorer onSelectFile={setSelectedKey} selectedKey={selectedKey} />
|
|
<div className="main" data-testid="main-area">
|
|
{selectedKey ? (
|
|
<DocumentEditor documentKey={selectedKey} />
|
|
) : (
|
|
<div data-testid="empty-state">未选择文档</div>
|
|
)}
|
|
</div>
|
|
{searchQuery !== '' && (
|
|
<SearchResults query={searchQuery} results={searchResults} onJumpToResult={handleJumpToResult} />
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|