Initial commit

This commit is contained in:
shiyu
2025-08-24 18:49:00 +08:00
parent 99866befe1
commit 6b0f2bd4fa
129 changed files with 11587 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
import { Layout, Flex } from 'antd';
import { memo, useState } from 'react';
import { useParams, useNavigate } from 'react-router';
import SideNav from '../layout/SideNav.tsx';
import TopHeader from '../layout/TopHeader.tsx';
import FileExplorerPage from '../pages/FileExplorerPage/FileExplorerPage.tsx';
import AdaptersPage from '../pages/AdaptersPage.tsx';
import SharePage from '../pages/SharePage.tsx';
import TasksPage from '../pages/TasksPage.tsx';
import OfflineDownloadPage from '../pages/OfflineDownloadPage.tsx';
import SystemSettingsPage from '../pages/SystemSettingsPage/SystemSettingsPage.tsx';
import LogsPage from '../pages/LogsPage.tsx';
import BackupPage from '../pages/SystemSettingsPage/BackupPage.tsx';
const LayoutShell = memo(function LayoutShell() {
const { navKey = 'files' } = useParams();
const navigate = useNavigate();
const [collapsed, setCollapsed] = useState(false);
return (
<Layout style={{ minHeight: '100vh' }}>
<SideNav
collapsed={collapsed}
onToggle={() => setCollapsed(c => !c)}
activeKey={navKey}
onChange={(key) => navigate(`/${key}`)}
/>
<Layout>
<TopHeader collapsed={collapsed} onToggle={() => setCollapsed(c => !c)} />
<Layout.Content style={{ padding: 16 }}>
<div style={{ minHeight: 'calc(100vh - 56px - 32px)' }}>
<Flex vertical gap={16}>
{navKey === 'adapters' && <AdaptersPage />}
{navKey === 'files' && <FileExplorerPage />}
{navKey === 'share' && <SharePage />}
{navKey === 'tasks' && <TasksPage />}
{navKey === 'offline' && <OfflineDownloadPage />}
{navKey === 'settings' && <SystemSettingsPage />}
{navKey === 'logs' && <LogsPage />}
{navKey === 'backup' && <BackupPage />}
{!['adapters','files','image','video','doc','fav','recent','recycle','share','tasks','offline','settings', 'logs', 'backup'].includes(navKey!) && <FileExplorerPage />}
</Flex>
</div>
</Layout.Content>
</Layout>
</Layout>
);
});
export default LayoutShell;

39
web/src/router/index.tsx Normal file
View File

@@ -0,0 +1,39 @@
import { Navigate, Routes, Route, useLocation } from 'react-router';
import type { RouteObject } from 'react-router';
import LayoutShell from './LayoutShell.tsx';
import LoginPage from '../pages/LoginPage.tsx';
import SetupPage from '../pages/SetupPage.tsx';
import PublicSharePage from '../pages/PublicSharePage.tsx';
import { useAuth } from '../contexts/AuthContext';
import type { JSX } from 'react';
export const routes: RouteObject[] = [
{ path: '/', element: <Navigate to="/files" replace /> },
{ path: '/:navKey/*', element: <LayoutShell /> },
{ path: '/login', element: <LoginPage /> },
{ path: '/share/:token', element: <PublicSharePage /> },
{ path: '/setup', element: <SetupPage /> },
];
function RequireAuth({ children }: { children: JSX.Element }) {
const { isAuthenticated } = useAuth();
const location = useLocation();
if (!isAuthenticated && !location.pathname.startsWith('/share/') && location.pathname !== '/login' && location.pathname !== '/register') {
return <Navigate to="/login" replace />;
}
return children;
}
export function AppRouter() {
return (
<RequireAuth>
<Routes>
{routes.map(r => (
<Route key={r.path} path={r.path} element={r.element} />
))}
</Routes>
</RequireAuth>
);
}
export default AppRouter;