
diff --git a/web/src/app/home/components/new-version-dialog/NewVersionDialog.tsx b/web/src/app/home/components/new-version-dialog/NewVersionDialog.tsx
index 97074728..920ed5f9 100644
--- a/web/src/app/home/components/new-version-dialog/NewVersionDialog.tsx
+++ b/web/src/app/home/components/new-version-dialog/NewVersionDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
diff --git a/web/src/app/home/components/password-change-dialog/PasswordChangeDialog.tsx b/web/src/app/home/components/password-change-dialog/PasswordChangeDialog.tsx
index 279eb265..843f9e90 100644
--- a/web/src/app/home/components/password-change-dialog/PasswordChangeDialog.tsx
+++ b/web/src/app/home/components/password-change-dialog/PasswordChangeDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import * as React from 'react';
import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
diff --git a/web/src/app/home/components/survey/SurveyWidget.tsx b/web/src/app/home/components/survey/SurveyWidget.tsx
index 96015b44..5e7dc06a 100644
--- a/web/src/app/home/components/survey/SurveyWidget.tsx
+++ b/web/src/app/home/components/survey/SurveyWidget.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState, useEffect, useCallback } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
import type {
diff --git a/web/src/app/home/knowledge/KBDetailContent.tsx b/web/src/app/home/knowledge/KBDetailContent.tsx
index ae14ff9c..43c79c07 100644
--- a/web/src/app/home/knowledge/KBDetailContent.tsx
+++ b/web/src/app/home/knowledge/KBDetailContent.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useState, useEffect, useCallback } from 'react';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import {
@@ -32,7 +30,7 @@ import { FileText, FolderOpen, Search, Trash2 } from 'lucide-react';
export default function KBDetailContent({ id }: { id: string }) {
const isCreateMode = id === 'new';
- const router = useRouter();
+ const navigate = useNavigate();
const { t } = useTranslation();
const { refreshKnowledgeBases, knowledgeBases, setDetailEntityName } =
useSidebarData();
@@ -84,12 +82,12 @@ export default function KBDetailContent({ id }: { id: string }) {
function handleKbDeleted() {
refreshKnowledgeBases();
- router.push('/home/knowledge');
+ navigate('/home/knowledge');
}
function handleNewKbCreated(newKbId: string) {
refreshKnowledgeBases();
- router.push(`/home/knowledge?id=${encodeURIComponent(newKbId)}`);
+ navigate(`/home/knowledge?id=${encodeURIComponent(newKbId)}`);
}
function handleKbUpdated() {
diff --git a/web/src/app/home/knowledge/components/kb-docs/documents/columns.tsx b/web/src/app/home/knowledge/components/kb-docs/documents/columns.tsx
index 2880c1ba..469d810d 100644
--- a/web/src/app/home/knowledge/components/kb-docs/documents/columns.tsx
+++ b/web/src/app/home/knowledge/components/kb-docs/documents/columns.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { ColumnDef } from '@tanstack/react-table';
import { MoreHorizontal } from 'lucide-react';
import { Button } from '@/components/ui/button';
diff --git a/web/src/app/home/knowledge/components/kb-docs/documents/data-table.tsx b/web/src/app/home/knowledge/components/kb-docs/documents/data-table.tsx
index 178ccad9..a7bbb310 100644
--- a/web/src/app/home/knowledge/components/kb-docs/documents/data-table.tsx
+++ b/web/src/app/home/knowledge/components/kb-docs/documents/data-table.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import {
ColumnDef,
flexRender,
diff --git a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx
index 025bdb92..af9250fb 100644
--- a/web/src/app/home/knowledge/components/kb-form/KBForm.tsx
+++ b/web/src/app/home/knowledge/components/kb-form/KBForm.tsx
@@ -1,5 +1,5 @@
import { useEffect, useMemo, useRef, useState } from 'react';
-import Link from 'next/link';
+import { Link } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
@@ -304,7 +304,7 @@ export default function KBForm({
{t('knowledge.noEnginesAvailable')}
{t('knowledge.installEngineHint')}
diff --git a/web/src/app/home/knowledge/components/kb-migration-dialog/KBMigrationDialog.tsx b/web/src/app/home/knowledge/components/kb-migration-dialog/KBMigrationDialog.tsx
index 8e04513b..facd3345 100644
--- a/web/src/app/home/knowledge/components/kb-migration-dialog/KBMigrationDialog.tsx
+++ b/web/src/app/home/knowledge/components/kb-migration-dialog/KBMigrationDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useState } from 'react';
import {
Dialog,
diff --git a/web/src/app/home/knowledge/components/kb-retrieve/KBRetrieveGeneric.tsx b/web/src/app/home/knowledge/components/kb-retrieve/KBRetrieveGeneric.tsx
index becdb0fe..5f158596 100644
--- a/web/src/app/home/knowledge/components/kb-retrieve/KBRetrieveGeneric.tsx
+++ b/web/src/app/home/knowledge/components/kb-retrieve/KBRetrieveGeneric.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
diff --git a/web/src/app/home/knowledge/page.tsx b/web/src/app/home/knowledge/page.tsx
index 49471d3c..66d21784 100644
--- a/web/src/app/home/knowledge/page.tsx
+++ b/web/src/app/home/knowledge/page.tsx
@@ -1,6 +1,4 @@
-'use client';
-
-import { useSearchParams } from 'next/navigation';
+import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useEffect, useState } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
@@ -10,7 +8,7 @@ import KBDetailContent from './KBDetailContent';
export default function KnowledgePage() {
const { t } = useTranslation();
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
const detailId = searchParams.get('id');
const { refreshKnowledgeBases } = useSidebarData();
diff --git a/web/src/app/home/layout.tsx b/web/src/app/home/layout.tsx
index 4119d968..55a66de7 100644
--- a/web/src/app/home/layout.tsx
+++ b/web/src/app/home/layout.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import HomeSidebar from '@/app/home/components/home-sidebar/HomeSidebar';
import SurveyWidget from '@/app/home/components/survey/SurveyWidget';
import React, {
@@ -21,8 +19,8 @@ import {
initializeUserInfo,
initializeSystemInfo,
} from '@/app/infra/http';
-import { usePathname, useRouter } from 'next/navigation';
-import Link from 'next/link';
+import { useNavigate, useLocation } from 'react-router-dom';
+import { Link } from 'react-router-dom';
import { extractI18nObject } from '@/i18n/I18nProvider';
import { CircleHelp } from 'lucide-react';
import { useTranslation } from 'react-i18next';
@@ -59,7 +57,7 @@ export default function HomeLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
- const router = useRouter();
+ const navigate = useNavigate();
// Initialize user info if not already initialized
useEffect(() => {
@@ -75,14 +73,14 @@ export default function HomeLayout({
// Always re-fetch to ensure we have the latest wizard_status from backend
await initializeSystemInfo();
if (systemInfo.wizard_status === 'none') {
- router.replace('/wizard');
+ navigate('/wizard');
}
} catch {
// If fetching system info fails, don't redirect
}
};
checkWizard();
- }, [router]);
+ }, [navigate]);
return (
@@ -101,7 +99,8 @@ function HomeLayoutInner({ children }: { children: React.ReactNode }) {
zh_Hans: '',
});
const { detailEntityName } = useSidebarData();
- const pathname = usePathname();
+ const location = useLocation();
+ const pathname = location.pathname;
const { t } = useTranslation();
const onSelectedChangeAction = useCallback((child: SidebarChildVO) => {
@@ -139,7 +138,7 @@ function HomeLayoutInner({ children }: { children: React.ReactNode }) {
- {sectionLabel}
+ {sectionLabel}
diff --git a/web/src/app/home/market/page.tsx b/web/src/app/home/market/page.tsx
index 88161973..e2158c53 100644
--- a/web/src/app/home/market/page.tsx
+++ b/web/src/app/home/market/page.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import MarketPage from '@/app/home/plugins/components/plugin-market/PluginMarketComponent';
import {
Dialog,
diff --git a/web/src/app/home/mcp/MCPDetailContent.tsx b/web/src/app/home/mcp/MCPDetailContent.tsx
index 90550ea2..8b4325a3 100644
--- a/web/src/app/home/mcp/MCPDetailContent.tsx
+++ b/web/src/app/home/mcp/MCPDetailContent.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useState, useEffect, useCallback, useRef } from 'react';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { Label } from '@/components/ui/label';
@@ -30,7 +28,7 @@ import { toast } from 'sonner';
export default function MCPDetailContent({ id }: { id: string }) {
const isCreateMode = id === 'new';
- const router = useRouter();
+ const navigate = useNavigate();
const { t } = useTranslation();
const { refreshMCPServers, mcpServers, setDetailEntityName } =
useSidebarData();
@@ -96,12 +94,12 @@ export default function MCPDetailContent({ id }: { id: string }) {
function handleServerDeleted() {
refreshMCPServers();
- router.push('/home/mcp');
+ navigate('/home/mcp');
}
function handleNewServerCreated(serverName: string) {
refreshMCPServers();
- router.push(`/home/mcp?id=${encodeURIComponent(serverName)}`);
+ navigate(`/home/mcp?id=${encodeURIComponent(serverName)}`);
}
function confirmDelete() {
diff --git a/web/src/app/home/mcp/components/mcp-form/MCPForm.tsx b/web/src/app/home/mcp/components/mcp-form/MCPForm.tsx
index 615b3156..f2732126 100644
--- a/web/src/app/home/mcp/components/mcp-form/MCPForm.tsx
+++ b/web/src/app/home/mcp/components/mcp-form/MCPForm.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, {
useState,
useEffect,
diff --git a/web/src/app/home/mcp/page.tsx b/web/src/app/home/mcp/page.tsx
index d09d3a26..391679c3 100644
--- a/web/src/app/home/mcp/page.tsx
+++ b/web/src/app/home/mcp/page.tsx
@@ -1,12 +1,10 @@
-'use client';
-
-import { useSearchParams } from 'next/navigation';
+import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import MCPDetailContent from './MCPDetailContent';
export default function MCPPage() {
const { t } = useTranslation();
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
const detailId = searchParams.get('id');
if (detailId) {
diff --git a/web/src/app/home/monitoring/components/ExportDropdown.tsx b/web/src/app/home/monitoring/components/ExportDropdown.tsx
index e8766827..47a3e87d 100644
--- a/web/src/app/home/monitoring/components/ExportDropdown.tsx
+++ b/web/src/app/home/monitoring/components/ExportDropdown.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
diff --git a/web/src/app/home/monitoring/components/FeedbackCard.tsx b/web/src/app/home/monitoring/components/FeedbackCard.tsx
index 29c4af96..5196fb89 100644
--- a/web/src/app/home/monitoring/components/FeedbackCard.tsx
+++ b/web/src/app/home/monitoring/components/FeedbackCard.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { useTranslation } from 'react-i18next';
import {
diff --git a/web/src/app/home/monitoring/components/FeedbackList.tsx b/web/src/app/home/monitoring/components/FeedbackList.tsx
index 9555eef5..407d5e56 100644
--- a/web/src/app/home/monitoring/components/FeedbackList.tsx
+++ b/web/src/app/home/monitoring/components/FeedbackList.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { useTranslation } from 'react-i18next';
import {
diff --git a/web/src/app/home/monitoring/components/MessageContentRenderer.tsx b/web/src/app/home/monitoring/components/MessageContentRenderer.tsx
index a5f412ee..c73a9818 100644
--- a/web/src/app/home/monitoring/components/MessageContentRenderer.tsx
+++ b/web/src/app/home/monitoring/components/MessageContentRenderer.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState } from 'react';
import {
MessageChainComponent,
diff --git a/web/src/app/home/monitoring/components/MessageDetailsCard.tsx b/web/src/app/home/monitoring/components/MessageDetailsCard.tsx
index 454354ff..e50b80d3 100644
--- a/web/src/app/home/monitoring/components/MessageDetailsCard.tsx
+++ b/web/src/app/home/monitoring/components/MessageDetailsCard.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { MessageDetails } from '../types/monitoring';
diff --git a/web/src/app/home/monitoring/components/filters/MonitoringFilters.tsx b/web/src/app/home/monitoring/components/filters/MonitoringFilters.tsx
index 9398cc6c..2dd2ee1f 100644
--- a/web/src/app/home/monitoring/components/filters/MonitoringFilters.tsx
+++ b/web/src/app/home/monitoring/components/filters/MonitoringFilters.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
diff --git a/web/src/app/home/monitoring/components/overview-cards/MetricCard.tsx b/web/src/app/home/monitoring/components/overview-cards/MetricCard.tsx
index 43fa6699..7c53e33d 100644
--- a/web/src/app/home/monitoring/components/overview-cards/MetricCard.tsx
+++ b/web/src/app/home/monitoring/components/overview-cards/MetricCard.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
diff --git a/web/src/app/home/monitoring/components/overview-cards/OverviewCards.tsx b/web/src/app/home/monitoring/components/overview-cards/OverviewCards.tsx
index 5a097a16..5dcc4b18 100644
--- a/web/src/app/home/monitoring/components/overview-cards/OverviewCards.tsx
+++ b/web/src/app/home/monitoring/components/overview-cards/OverviewCards.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { useTranslation } from 'react-i18next';
import MetricCard from './MetricCard';
diff --git a/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx b/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx
index f6b5d6e7..d1d82b6e 100644
--- a/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx
+++ b/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
diff --git a/web/src/app/home/monitoring/hooks/useMonitoringFilters.ts b/web/src/app/home/monitoring/hooks/useMonitoringFilters.ts
index aaa914f0..53545bab 100644
--- a/web/src/app/home/monitoring/hooks/useMonitoringFilters.ts
+++ b/web/src/app/home/monitoring/hooks/useMonitoringFilters.ts
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { useSearchParams } from 'next/navigation';
+import { useSearchParams } from 'react-router-dom';
import { FilterState, TimeRangeOption, DateRange } from '../types/monitoring';
import { getPresetDateRange } from '../utils/dateUtils';
@@ -7,7 +7,7 @@ import { getPresetDateRange } from '../utils/dateUtils';
* Custom hook for managing monitoring filters
*/
export function useMonitoringFilters() {
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
// Initialize filters from URL params
const [selectedBots, setSelectedBots] = useState(() => {
diff --git a/web/src/app/home/monitoring/page.tsx b/web/src/app/home/monitoring/page.tsx
index f3e4cd3c..02a60580 100644
--- a/web/src/app/home/monitoring/page.tsx
+++ b/web/src/app/home/monitoring/page.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { Suspense, useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
diff --git a/web/src/app/home/pipelines/PipelineDetailContent.tsx b/web/src/app/home/pipelines/PipelineDetailContent.tsx
index 3652387b..2b8c76c1 100644
--- a/web/src/app/home/pipelines/PipelineDetailContent.tsx
+++ b/web/src/app/home/pipelines/PipelineDetailContent.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useState, useEffect } from 'react';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import PipelineFormComponent from '@/app/home/pipelines/components/pipeline-form/PipelineFormComponent';
@@ -13,7 +11,7 @@ import { Settings, Bug, BarChart3 } from 'lucide-react';
export default function PipelineDetailContent({ id }: { id: string }) {
const isCreateMode = id === 'new';
- const router = useRouter();
+ const navigate = useNavigate();
const { t } = useTranslation();
const { refreshPipelines, pipelines, setDetailEntityName } = useSidebarData();
@@ -38,7 +36,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
function handleNewPipelineCreated(newPipelineId: string) {
refreshPipelines();
- router.push(`/home/pipelines?id=${encodeURIComponent(newPipelineId)}`);
+ navigate(`/home/pipelines?id=${encodeURIComponent(newPipelineId)}`);
}
// ==================== Create Mode ====================
@@ -73,7 +71,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
function handleDeletePipeline() {
refreshPipelines();
- router.push('/home/pipelines');
+ navigate('/home/pipelines');
}
// ==================== Edit Mode ====================
@@ -129,7 +127,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
onFinish={handleFinish}
onNewPipelineCreated={handleNewPipelineCreated}
onDeletePipeline={handleDeletePipeline}
- onCancel={() => router.push('/home/pipelines')}
+ onCancel={() => navigate('/home/pipelines')}
onDirtyChange={setFormDirty}
/>
@@ -152,7 +150,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
{
- router.push('/home/monitoring');
+ navigate('/home/monitoring');
}}
/>
diff --git a/web/src/app/home/pipelines/components/monitoring-tab/PipelineMonitoringTab.tsx b/web/src/app/home/pipelines/components/monitoring-tab/PipelineMonitoringTab.tsx
index b2c65f8f..bd59b4da 100644
--- a/web/src/app/home/pipelines/components/monitoring-tab/PipelineMonitoringTab.tsx
+++ b/web/src/app/home/pipelines/components/monitoring-tab/PipelineMonitoringTab.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
diff --git a/web/src/app/home/pipelines/components/pipeline-extensions/PipelineExtension.tsx b/web/src/app/home/pipelines/components/pipeline-extensions/PipelineExtension.tsx
index 2f411f4e..e1ee3492 100644
--- a/web/src/app/home/pipelines/components/pipeline-extensions/PipelineExtension.tsx
+++ b/web/src/app/home/pipelines/components/pipeline-extensions/PipelineExtension.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { backendClient } from '@/app/infra/http';
diff --git a/web/src/app/home/pipelines/page.tsx b/web/src/app/home/pipelines/page.tsx
index b3432847..be65346a 100644
--- a/web/src/app/home/pipelines/page.tsx
+++ b/web/src/app/home/pipelines/page.tsx
@@ -1,12 +1,10 @@
-'use client';
-
-import { useSearchParams } from 'next/navigation';
+import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import PipelineDetailContent from './PipelineDetailContent';
export default function PipelineConfigPage() {
const { t } = useTranslation();
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
const detailId = searchParams.get('id');
if (detailId) {
diff --git a/web/src/app/home/plugins/PluginDetailContent.tsx b/web/src/app/home/plugins/PluginDetailContent.tsx
index 71a66533..30d1f8bb 100644
--- a/web/src/app/home/plugins/PluginDetailContent.tsx
+++ b/web/src/app/home/plugins/PluginDetailContent.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useEffect } from 'react';
import PluginForm from '@/app/home/plugins/components/plugin-installed/plugin-form/PluginForm';
import PluginReadme from '@/app/home/plugins/components/plugin-installed/plugin-readme/PluginReadme';
diff --git a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallProgressDialog.tsx b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallProgressDialog.tsx
index 3d29dc9f..f1753265 100644
--- a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallProgressDialog.tsx
+++ b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallProgressDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import {
Dialog,
diff --git a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskContext.tsx b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskContext.tsx
index 0330bc8a..a64d3f81 100644
--- a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskContext.tsx
+++ b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskContext.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, {
createContext,
useContext,
diff --git a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskQueue.tsx b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskQueue.tsx
index 86d8c6f0..6675a743 100644
--- a/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskQueue.tsx
+++ b/web/src/app/home/plugins/components/plugin-install-task/PluginInstallTaskQueue.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Progress } from '@/components/ui/progress';
diff --git a/web/src/app/home/plugins/components/plugin-installed/PluginInstalledComponent.tsx b/web/src/app/home/plugins/components/plugin-installed/PluginInstalledComponent.tsx
index 7c496d8e..f4df16e1 100644
--- a/web/src/app/home/plugins/components/plugin-installed/PluginInstalledComponent.tsx
+++ b/web/src/app/home/plugins/components/plugin-installed/PluginInstalledComponent.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { PluginCardVO } from '@/app/home/plugins/components/plugin-installed/PluginCardVO';
import PluginCardComponent from '@/app/home/plugins/components/plugin-installed/plugin-card/PluginCardComponent';
import styles from '@/app/home/plugins/plugins.module.css';
@@ -33,11 +31,10 @@ enum PluginOperationType {
UPDATE = 'UPDATE',
}
-// eslint-disable-next-line react/display-name
const PluginInstalledComponent = forwardRef(
(props, ref) => {
const { t } = useTranslation();
- const router = useRouter();
+ const navigate = useNavigate();
const { refreshPlugins } = useSidebarData();
const [pluginList, setPluginList] = useState([]);
const [showOperationModal, setShowOperationModal] = useState(false);
@@ -163,7 +160,7 @@ const PluginInstalledComponent = forwardRef(
function handlePluginClick(plugin: PluginCardVO) {
const pluginId = `${plugin.author}/${plugin.name}`;
- router.push(`/home/plugins?id=${encodeURIComponent(pluginId)}`);
+ navigate(`/home/plugins?id=${encodeURIComponent(pluginId)}`);
}
function handlePluginDelete(plugin: PluginCardVO) {
diff --git a/web/src/app/home/plugins/components/plugin-market/PluginMarketComponent.tsx b/web/src/app/home/plugins/components/plugin-market/PluginMarketComponent.tsx
index 0c185cdc..2b898cca 100644
--- a/web/src/app/home/plugins/components/plugin-market/PluginMarketComponent.tsx
+++ b/web/src/app/home/plugins/components/plugin-market/PluginMarketComponent.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useState, useEffect, useCallback, useRef, Suspense } from 'react';
-import { useSearchParams } from 'next/navigation';
+import { useSearchParams } from 'react-router-dom';
import { Input } from '@/components/ui/input';
import {
Select,
@@ -47,7 +45,7 @@ function MarketPageContent({
installPlugin: (plugin: PluginV4) => void;
}) {
const { t } = useTranslation();
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
const validCategories = [
'Tool',
diff --git a/web/src/app/home/plugins/components/plugin-market/RecommendationLists.tsx b/web/src/app/home/plugins/components/plugin-market/RecommendationLists.tsx
index 01ce0b4a..20eafdde 100644
--- a/web/src/app/home/plugins/components/plugin-market/RecommendationLists.tsx
+++ b/web/src/app/home/plugins/components/plugin-market/RecommendationLists.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useState, useRef, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight, Star } from 'lucide-react';
import { Button } from '@/components/ui/button';
diff --git a/web/src/app/home/plugins/components/plugin-market/TagsFilter.tsx b/web/src/app/home/plugins/components/plugin-market/TagsFilter.tsx
index 3b1ca204..65bf15a5 100644
--- a/web/src/app/home/plugins/components/plugin-market/TagsFilter.tsx
+++ b/web/src/app/home/plugins/components/plugin-market/TagsFilter.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useTranslation } from 'react-i18next';
import {
Select,
diff --git a/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx b/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
index 6a85a279..c07b271e 100644
--- a/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
+++ b/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import { useEffect, useState, useRef } from 'react';
import MCPCardComponent from '@/app/home/plugins/mcp-server/mcp-card/MCPCardComponent';
import { MCPCardVO } from '@/app/home/plugins/mcp-server/MCPCardVO';
diff --git a/web/src/app/home/plugins/mcp-server/mcp-form/MCPDeleteConfirmDialog.tsx b/web/src/app/home/plugins/mcp-server/mcp-form/MCPDeleteConfirmDialog.tsx
index cf40a20c..44315a88 100644
--- a/web/src/app/home/plugins/mcp-server/mcp-form/MCPDeleteConfirmDialog.tsx
+++ b/web/src/app/home/plugins/mcp-server/mcp-form/MCPDeleteConfirmDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
diff --git a/web/src/app/home/plugins/mcp-server/mcp-form/MCPFormDialog.tsx b/web/src/app/home/plugins/mcp-server/mcp-form/MCPFormDialog.tsx
index 9675e0ba..93b8292b 100644
--- a/web/src/app/home/plugins/mcp-server/mcp-form/MCPFormDialog.tsx
+++ b/web/src/app/home/plugins/mcp-server/mcp-form/MCPFormDialog.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React, { useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Resolver, useForm } from 'react-hook-form';
diff --git a/web/src/app/home/plugins/page.tsx b/web/src/app/home/plugins/page.tsx
index 502c6c53..0e4b4fb8 100644
--- a/web/src/app/home/plugins/page.tsx
+++ b/web/src/app/home/plugins/page.tsx
@@ -1,4 +1,3 @@
-'use client';
import PluginInstalledComponent, {
PluginInstalledComponentRef,
} from '@/app/home/plugins/components/plugin-installed/PluginInstalledComponent';
@@ -45,7 +44,7 @@ import {
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import React, { useState, useRef, useCallback, useEffect } from 'react';
-import { useSearchParams, useRouter } from 'next/navigation';
+import { useNavigate, useSearchParams } from 'react-router-dom';
import { httpClient } from '@/app/infra/http/HttpClient';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
@@ -84,7 +83,7 @@ interface GithubAsset {
}
export default function PluginConfigPage() {
- const searchParams = useSearchParams();
+ const [searchParams] = useSearchParams();
const detailId = searchParams.get('id');
// Show plugin detail view when ?id= query param is present
@@ -97,7 +96,7 @@ export default function PluginConfigPage() {
function PluginListView() {
const { t } = useTranslation();
- const router = useRouter();
+ const navigate = useNavigate();
const {
refreshPlugins,
pendingPluginInstallAction,
@@ -672,7 +671,7 @@ function PluginListView() {
{systemInfo.enable_marketplace && (
{
- router.push('/home/market');
+ navigate('/home/market');
}}
>
diff --git a/web/src/app/infra/http/index.ts b/web/src/app/infra/http/index.ts
index 4a9002a5..b992545d 100644
--- a/web/src/app/infra/http/index.ts
+++ b/web/src/app/infra/http/index.ts
@@ -31,8 +31,8 @@ export let userInfo: {
* 获取基础 URL
*/
const getBaseURL = (): string => {
- if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_API_BASE_URL) {
- return process.env.NEXT_PUBLIC_API_BASE_URL;
+ if (typeof window !== 'undefined' && import.meta.env.VITE_API_BASE_URL) {
+ return import.meta.env.VITE_API_BASE_URL;
}
return '/';
};
diff --git a/web/src/app/infra/websocket/WebSocketClient.ts b/web/src/app/infra/websocket/WebSocketClient.ts
index 922b90a3..b1098c1e 100644
--- a/web/src/app/infra/websocket/WebSocketClient.ts
+++ b/web/src/app/infra/websocket/WebSocketClient.ts
@@ -78,10 +78,10 @@ export class WebSocketClient {
// 构建WebSocket URL
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
- // extract host from process.env.NEXT_PUBLIC_API_BASE_URL
- // 如果环境变量未定义,使用当前页面的 host (适配生产环境)
+ // extract host from import.meta.env.VITE_API_BASE_URL
+ // If env var is undefined, use current page host (for production)
const host =
- process.env.NEXT_PUBLIC_API_BASE_URL?.split('://')[1] ||
+ import.meta.env.VITE_API_BASE_URL?.split('://')[1] ||
window.location.host;
const url = `${protocol}//${host}/api/v1/pipelines/${this.pipelineId}/ws/connect?session_type=${this.sessionType}`;
diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx
deleted file mode 100644
index 592f2330..00000000
--- a/web/src/app/layout.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import './global.css';
-import 'react-photo-view/dist/react-photo-view.css';
-import type { Metadata } from 'next';
-import { Toaster } from '@/components/ui/sonner';
-import I18nProvider from '@/i18n/I18nProvider';
-import { ThemeProvider } from '@/components/providers/theme-provider';
-
-export const metadata: Metadata = {
- title: 'LangBot',
- description:
- 'Production-grade platform for building agentic IM bots, integrated with Telegram, Slack, Discord, WeChat, QQ, etc.',
-};
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
-
- {children}
-
-
-
-
-
- );
-}
diff --git a/web/src/app/login/layout.tsx b/web/src/app/login/layout.tsx
index 4996a7ac..2d7e7f80 100644
--- a/web/src/app/login/layout.tsx
+++ b/web/src/app/login/layout.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
export default function LoginLayout({
diff --git a/web/src/app/login/page.tsx b/web/src/app/login/page.tsx
index 253ece72..51bd0fb8 100644
--- a/web/src/app/login/page.tsx
+++ b/web/src/app/login/page.tsx
@@ -1,4 +1,3 @@
-'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@@ -22,12 +21,12 @@ import {
} from '@/components/ui/form';
import { useEffect, useState } from 'react';
import { httpClient, initializeUserInfo } from '@/app/infra/http';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { Mail, Lock, Loader2, AlertCircle, RefreshCw } from 'lucide-react';
import langbotIcon from '@/app/assets/langbot-logo.webp';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
-import Link from 'next/link';
+import { Link } from 'react-router-dom';
import { ThemeToggle } from '@/components/ui/theme-toggle';
import { LoadingSpinner } from '@/components/ui/loading-spinner';
@@ -40,7 +39,7 @@ const formSchema = (t: (key: string) => string) =>
type AccountType = 'local' | 'space';
export default function Login() {
- const router = useRouter();
+ const navigate = useNavigate();
const { t } = useTranslation();
const [spaceLoading, setSpaceLoading] = useState(false);
const [accountType, setAccountType] = useState(null);
@@ -66,7 +65,7 @@ export default function Login() {
setLoadError(null);
const res = await httpClient.getAccountInfo();
if (!res.initialized) {
- router.push('/register');
+ navigate('/register');
return;
}
setAccountType(res.account_type || 'local');
@@ -97,7 +96,7 @@ export default function Login() {
.then((res) => {
if (res.token) {
localStorage.setItem('token', res.token);
- router.push('/home');
+ navigate('/home');
}
})
.catch(() => {});
@@ -114,7 +113,7 @@ export default function Login() {
localStorage.setItem('token', res.token);
localStorage.setItem('userEmail', username);
await initializeUserInfo();
- router.push('/home');
+ navigate('/home');
toast.success(t('common.loginSuccess'));
})
.catch(() => {
@@ -154,7 +153,7 @@ export default function Login() {
{t('common.password')}
{t('common.forgotPassword')}
diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx
index c2943fe9..85ebd624 100644
--- a/web/src/app/page.tsx
+++ b/web/src/app/page.tsx
@@ -1,12 +1,10 @@
-'use client';
-
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';
export default function Home() {
- const router = useRouter();
+ const navigate = useNavigate();
useEffect(() => {
- router.push('/login');
+ navigate('/login');
}, []);
return
;
}
diff --git a/web/src/app/register/layout.tsx b/web/src/app/register/layout.tsx
index c93e0bde..d4a0c041 100644
--- a/web/src/app/register/layout.tsx
+++ b/web/src/app/register/layout.tsx
@@ -1,5 +1,3 @@
-'use client';
-
import React from 'react';
export default function RegisterLayout({
diff --git a/web/src/app/register/page.tsx b/web/src/app/register/page.tsx
index 54660f57..13042082 100644
--- a/web/src/app/register/page.tsx
+++ b/web/src/app/register/page.tsx
@@ -1,4 +1,3 @@
-'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@@ -22,7 +21,7 @@ import {
} from '@/components/ui/form';
import { useEffect, useState } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { Mail, Lock, Loader2, Info } from 'lucide-react';
import {
Popover,
@@ -42,7 +41,7 @@ const formSchema = (t: (key: string) => string) =>
});
export default function Register() {
- const router = useRouter();
+ const navigate = useNavigate();
const { t } = useTranslation();
const [spaceLoading, setSpaceLoading] = useState(false);
@@ -63,7 +62,7 @@ export default function Register() {
.checkIfInited()
.then((res) => {
if (res.initialized) {
- router.push('/login');
+ navigate('/login');
}
})
.catch(() => {});
@@ -78,7 +77,7 @@ export default function Register() {
.initUser(username, password)
.then(() => {
toast.success(t('register.initSuccess'));
- router.push('/login');
+ navigate('/login');
})
.catch((err: Error) => {
toast.error(t('register.initFailed') + (err as CustomApiError).msg);
@@ -114,7 +113,7 @@ export default function Register() {
diff --git a/web/src/app/wizard/page.tsx b/web/src/app/wizard/page.tsx
index 3d5e435f..bc085c12 100644
--- a/web/src/app/wizard/page.tsx
+++ b/web/src/app/wizard/page.tsx
@@ -1,7 +1,5 @@
-'use client';
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { useRouter } from 'next/navigation';
+import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { UUID } from 'uuidjs';
import { toast } from 'sonner';
@@ -81,7 +79,7 @@ const TOTAL_STEPS = 4;
export default function WizardPage() {
const { t } = useTranslation();
- const router = useRouter();
+ const navigate = useNavigate();
// ---- Wizard state ----
const [currentStep, setCurrentStep] = useState(0);
@@ -519,8 +517,8 @@ export default function WizardPage() {
}
setIsSkipping(false);
setShowSkipConfirm(false);
- router.push('/home');
- }, [router, t]);
+ navigate('/home');
+ }, [navigate, t]);
// ---- Render ----
@@ -1169,7 +1167,7 @@ function StepAIEngine({
function StepDone() {
const { t } = useTranslation();
- const router = useRouter();
+ const navigate = useNavigate();
const [particles] = useState(() =>
Array.from({ length: 30 }, (_, i) => ({
@@ -1213,8 +1211,8 @@ function StepDone() {
return;
}
setIsCompleting(false);
- router.push('/home/bots');
- }, [router, t]);
+ navigate('/home/bots');
+ }, [navigate, t]);
return (
@@ -1244,7 +1242,7 @@ function StepDone() {
{t('wizard.done.backToWorkbench')}
-