NapCatQQ/packages/napcat-webui-frontend/src/App.tsx
手瓜一十雪 c2d3a8034d Add plugin store feature to backend and frontend
Implemented plugin store API endpoints and types in the backend, including mock data and handlers for listing, detail, and install actions. Added plugin store page, card component, and related logic to the frontend, with navigation and categorized browsing. Updated plugin manager controller and site config to support the new plugin store functionality.
2026-01-24 12:00:26 +08:00

92 lines
3.1 KiB
TypeScript

import { Suspense, lazy, useEffect } from 'react';
import { Provider } from 'react-redux';
import { Route, Routes, useNavigate } from 'react-router-dom';
import PageBackground from '@/components/page_background';
import PageLoading from '@/components/page_loading';
import Toaster from '@/components/toaster';
import DialogProvider from '@/contexts/dialog';
import useAuth from '@/hooks/auth';
import store from '@/store';
const WebLoginPage = lazy(() => import('@/pages/web_login'));
const IndexPage = lazy(() => import('@/pages/index'));
const QQLoginPage = lazy(() => import('@/pages/qq_login'));
const DashboardIndexPage = lazy(() => import('@/pages/dashboard'));
const AboutPage = lazy(() => import('@/pages/dashboard/about'));
const ConfigPage = lazy(() => import('@/pages/dashboard/config'));
const DebugPage = lazy(() => import('@/pages/dashboard/debug'));
const HttpDebug = lazy(() => import('@/pages/dashboard/debug/http'));
const WSDebug = lazy(() => import('@/pages/dashboard/debug/websocket'));
const FileManagerPage = lazy(() => import('@/pages/dashboard/file_manager'));
const LogsPage = lazy(() => import('@/pages/dashboard/logs'));
const NetworkPage = lazy(() => import('@/pages/dashboard/network'));
const TerminalPage = lazy(() => import('@/pages/dashboard/terminal'));
const PluginPage = lazy(() => import('@/pages/dashboard/plugin'));
const PluginStorePage = lazy(() => import('@/pages/dashboard/plugin_store'));
function App () {
return (
<DialogProvider>
<Provider store={store}>
<PageBackground />
<Toaster />
<Suspense fallback={<PageLoading />}>
<AuthChecker>
<AppRoutes />
</AuthChecker>
</Suspense>
</Provider>
</DialogProvider>
);
}
function AuthChecker ({ children }: { children: React.ReactNode; }) {
const { isAuth } = useAuth();
const navigate = useNavigate();
useEffect(() => {
if (!isAuth) {
const search = new URLSearchParams(window.location.search);
const token = search.get('token');
let url = '/web_login';
if (token) {
url += `?token=${token}`;
}
navigate(url, { replace: true });
}
}, [isAuth, navigate]);
return <>{children}</>;
}
function AppRoutes () {
return (
<Routes>
<Route path='/' element={<IndexPage />}>
<Route index element={<DashboardIndexPage />} />
<Route path='network' element={<NetworkPage />} />
<Route path='config' element={<ConfigPage />} />
<Route path='logs' element={<LogsPage />} />
<Route path='debug' element={<DebugPage />}>
<Route path='ws' element={<WSDebug />} />
<Route path='http' element={<HttpDebug />} />
</Route>
<Route path='file_manager' element={<FileManagerPage />} />
<Route path='terminal' element={<TerminalPage />} />
<Route path='plugins' element={<PluginPage />} />
<Route path='plugin_store' element={<PluginStorePage />} />
<Route path='about' element={<AboutPage />} />
</Route>
<Route path='/qq_login' element={<QQLoginPage />} />
<Route path='/web_login' element={<WebLoginPage />} />
</Routes>
);
}
export default App;