refactor(web): migrate from Next.js to Vite + React Router

This commit is contained in:
RockChinQ
2026-04-03 11:24:14 +08:00
parent e701daa8e0
commit 2a4ba237c4
1441 changed files with 917663 additions and 3671 deletions
+7 -7
View File
@@ -1,7 +1,7 @@
'use client';
import { useEffect, useState, useCallback, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useNavigate } from 'react-router-dom';
import { httpClient } from '@/app/infra/http/HttpClient';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
@@ -23,7 +23,7 @@ import { LoadingSpinner } from '@/components/ui/loading-spinner';
import langbotIcon from '@/app/assets/langbot-logo.webp';
function SpaceOAuthCallbackContent() {
const router = useRouter();
const navigate = useNavigate();
const searchParams = useSearchParams();
const { t } = useTranslation();
@@ -51,7 +51,7 @@ function SpaceOAuthCallbackContent() {
const wizardState = localStorage.getItem('langbot_wizard_state');
const redirectTo = wizardState ? '/wizard' : '/home';
setTimeout(() => {
router.push(redirectTo);
navigate(redirectTo);
}, 1000);
} catch (err) {
setStatus('error');
@@ -81,7 +81,7 @@ function SpaceOAuthCallbackContent() {
setStatus('success');
toast.success(t('account.bindSpaceSuccess'));
setTimeout(() => {
router.push('/home');
navigate('/home');
}, 1000);
} catch (err) {
setStatus('error');
@@ -146,7 +146,7 @@ function SpaceOAuthCallbackContent() {
};
const handleCancelBind = () => {
router.push('/home');
navigate('/home');
};
return (
@@ -217,7 +217,7 @@ function SpaceOAuthCallbackContent() {
<>
<AlertCircle className="h-12 w-12 text-red-500" />
<Button
onClick={() => router.push(isBindMode ? '/home' : '/login')}
onClick={() => navigate(isBindMode ? '/home' : '/login')}
className="w-full mt-4"
>
{isBindMode ? t('common.backToHome') : t('common.backToLogin')}
+2 -2
View File
@@ -1,3 +1,5 @@
@import "tailwindcss";
@import "tw-animate-css";
:root {
/* 适用于 Firefox 的滚动条 */
scrollbar-color: rgba(0, 0, 0, 0.2) transparent; /* 滑块颜色 + 轨道颜色 */
@@ -72,9 +74,7 @@
}
}
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
+5 -5
View File
@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect, useRef, 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 { Switch } from '@/components/ui/switch';
@@ -34,7 +34,7 @@ import { toast } from 'sonner';
export default function BotDetailContent({ id }: { id: string }) {
const isCreateMode = id === 'new';
const router = useRouter();
const navigate = useNavigate();
const { t } = useTranslation();
const { refreshBots, bots, setDetailEntityName } = useSidebarData();
@@ -105,12 +105,12 @@ export default function BotDetailContent({ id }: { id: string }) {
function handleBotDeleted() {
refreshBots();
router.push('/home/bots');
navigate('/home/bots');
}
function handleNewBotCreated(newBotId: string) {
refreshBots();
router.push(`/home/bots?id=${encodeURIComponent(newBotId)}`);
navigate(`/home/bots?id=${encodeURIComponent(newBotId)}`);
}
function confirmDelete() {
@@ -1,4 +1,4 @@
'use client';
import { useState } from 'react';
import { BotLog } from '@/app/infra/http/requestParam/bots/GetBotLogsResponse';
@@ -1,4 +1,4 @@
'use client';
import { BotLogManager } from '@/app/home/bots/components/bot-log/BotLogManager';
import { useCallback, useEffect, useRef, useState, useMemo } from 'react';
@@ -15,7 +15,7 @@ import { Checkbox } from '@/components/ui/checkbox';
import { ChevronDownIcon, ExternalLink } from 'lucide-react';
import { debounce } from 'lodash';
import { useTranslation } from 'react-i18next';
import { useRouter } from 'next/navigation';
import { useNavigate } from 'react-router-dom';
export function BotLogListComponent({
botId,
@@ -32,7 +32,7 @@ export function BotLogListComponent({
hideToolbar?: boolean;
}) {
const { t } = useTranslation();
const router = useRouter();
const navigate = useNavigate();
const manager = useRef(new BotLogManager(botId)).current;
const [botLogList, setBotLogList] = useState<BotLog[]>([]);
const [autoFlush, setAutoFlush] = useState(true);
@@ -231,7 +231,7 @@ export function BotLogListComponent({
variant="outline"
size="sm"
className="gap-1"
onClick={() => router.push(`/home/monitoring?botId=${botId}`)}
onClick={() => navigate(`/home/monitoring?botId=${botId}`)}
>
<ExternalLink className="size-3.5" />
<span className="text-sm">{t('bots.viewDetailedLogs')}</span>
@@ -1,4 +1,4 @@
'use client';
import React, {
useState,
+2 -2
View File
@@ -1,6 +1,6 @@
'use client';
import { useSearchParams } from 'next/navigation';
import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import BotDetailContent from './BotDetailContent';
@@ -1,4 +1,4 @@
'use client';
import * as React from 'react';
import { useState, useEffect } from 'react';
@@ -1,11 +1,11 @@
'use client';
import * as React from 'react';
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { Copy, Check, Trash2, Plus } from 'lucide-react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { useNavigate } from 'react-router-dom';
import {
Dialog,
DialogContent,
@@ -67,8 +67,9 @@ export default function ApiIntegrationDialog({
onOpenChange,
}: ApiIntegrationDialogProps) {
const { t } = useTranslation();
const router = useRouter();
const pathname = usePathname();
const navigate = useNavigate();
const location = useLocation();
const pathname = location.pathname;;
const searchParams = useSearchParams();
const [activeTab, setActiveTab] = useState('apikeys');
const [apiKeys, setApiKeys] = useState<ApiKey[]>([]);
@@ -94,7 +95,7 @@ export default function ApiIntegrationDialog({
if (open) {
const params = new URLSearchParams(searchParams.toString());
params.set('action', 'showApiIntegrationSettings');
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
navigate(`${pathname}?${params.toString()}`, { scroll: false });
}
}, [open]);
@@ -108,7 +109,7 @@ export default function ApiIntegrationDialog({
const newUrl = params.toString()
? `${pathname}?${params.toString()}`
: pathname;
router.replace(newUrl, { scroll: false });
navigate(newUrl, { scroll: false });
}
onOpenChange(newOpen);
};
@@ -1,8 +1,8 @@
'use client';
import { useEffect, useState } from 'react';
import { SidebarChildVO } from '@/app/home/components/home-sidebar/HomeSidebarChild';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { useNavigate } from 'react-router-dom';
import { sidebarConfigList } from '@/app/home/components/home-sidebar/sidbarConfigList';
import langbotIcon from '@/app/assets/langbot-logo.webp';
import { systemInfo, httpClient } from '@/app/infra/http/HttpClient';
@@ -29,7 +29,7 @@ import {
Github,
Zap,
} from 'lucide-react';
import { useTheme } from 'next-themes';
import { useTheme } from '@/components/providers/theme-provider';
import {
DropdownMenu,
@@ -244,8 +244,9 @@ function NavItems({
sectionOpenState: Record<string, boolean>;
onSectionToggle: (id: string, open: boolean) => void;
}) {
const router = useRouter();
const pathname = usePathname();
const navigate = useNavigate();
const location = useLocation();
const pathname = location.pathname;;
const searchParams = useSearchParams();
const sidebarData = useSidebarData();
const { setPendingPluginInstallAction } = sidebarData;
@@ -413,7 +414,7 @@ function NavItems({
'bg-accent text-accent-foreground font-medium',
)}
onClick={() => {
router.push(itemRoute);
navigate(itemRoute);
setPopoverOpen((prev) => ({
...prev,
[config.id]: false,
@@ -471,7 +472,7 @@ function NavItems({
)}
onClick={(e) => {
e.preventDefault();
router.push(itemRoute);
navigate(itemRoute);
}}
>
{item.emoji ? (
@@ -623,7 +624,7 @@ function NavItems({
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
router.push('/home/market');
navigate('/home/market');
setPopoverOpen((prev) => ({
...prev,
[config.id]: false,
@@ -638,7 +639,7 @@ function NavItems({
onClick={(e) => {
e.stopPropagation();
setPendingPluginInstallAction('local');
router.push('/home/plugins');
navigate('/home/plugins');
setPopoverOpen((prev) => ({
...prev,
[config.id]: false,
@@ -652,7 +653,7 @@ function NavItems({
onClick={(e) => {
e.stopPropagation();
setPendingPluginInstallAction('github');
router.push('/home/plugins');
navigate('/home/plugins');
setPopoverOpen((prev) => ({
...prev,
[config.id]: false,
@@ -669,7 +670,7 @@ function NavItems({
type="button"
className="p-1 rounded-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
onClick={() => {
router.push(`${routePrefix}?id=new`);
navigate(`${routePrefix}?id=new`);
setPopoverOpen((prev) => ({
...prev,
[config.id]: false,
@@ -731,7 +732,7 @@ function NavItems({
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
router.push('/home/market');
navigate('/home/market');
}}
>
<Store className="size-4" />
@@ -742,7 +743,7 @@ function NavItems({
onClick={(e) => {
e.stopPropagation();
setPendingPluginInstallAction('local');
router.push('/home/plugins');
navigate('/home/plugins');
}}
>
<Upload className="size-4" />
@@ -752,7 +753,7 @@ function NavItems({
onClick={(e) => {
e.stopPropagation();
setPendingPluginInstallAction('github');
router.push('/home/plugins');
navigate('/home/plugins');
}}
>
<Github className="size-4" />
@@ -766,7 +767,7 @@ function NavItems({
className="p-1 rounded-sm text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground opacity-0 group-hover/category-header:opacity-100 transition-all"
onClick={(e) => {
e.stopPropagation();
router.push(`${routePrefix}?id=new`);
navigate(`${routePrefix}?id=new`);
}}
>
<Plus className="size-3.5" />
@@ -1029,8 +1030,9 @@ export default function HomeSidebar({
}: {
onSelectedChangeAction: (sidebarChild: SidebarChildVO) => void;
}) {
const router = useRouter();
const pathname = usePathname();
const navigate = useNavigate();
const location = useLocation();
const pathname = location.pathname;;
const searchParams = useSearchParams();
const { isMobile } = useSidebar();
@@ -1071,14 +1073,14 @@ export default function HomeSidebar({
if (open) {
const params = new URLSearchParams(searchParams.toString());
params.set('action', 'showModelSettings');
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
navigate(`${pathname}?${params.toString()}`, { scroll: false });
} else {
const params = new URLSearchParams(searchParams.toString());
params.delete('action');
const newUrl = params.toString()
? `${pathname}?${params.toString()}`
: pathname;
router.replace(newUrl, { scroll: false });
navigate(newUrl, { scroll: false });
}
}
@@ -1087,14 +1089,14 @@ export default function HomeSidebar({
if (open) {
const params = new URLSearchParams(searchParams.toString());
params.set('action', 'showAccountSettings');
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
navigate(`${pathname}?${params.toString()}`, { scroll: false });
} else {
const params = new URLSearchParams(searchParams.toString());
params.delete('action');
const newUrl = params.toString()
? `${pathname}?${params.toString()}`
: pathname;
router.replace(newUrl, { scroll: false });
navigate(newUrl, { scroll: false });
}
}
@@ -1165,7 +1167,7 @@ export default function HomeSidebar({
// User click: update state AND navigate
function handleChildClick(child: SidebarChildVO) {
selectChild(child);
router.push(child.route);
navigate(child.route);
}
function initSelect() {
@@ -1406,7 +1408,7 @@ export default function HomeSidebar({
<DropdownMenuItem
onClick={() => {
setUserMenuOpen(false);
router.push('/wizard');
navigate('/wizard');
}}
>
<Zap className="text-blue-500" />
@@ -1,4 +1,4 @@
'use client';
import React, {
createContext,
@@ -1,4 +1,4 @@
'use client';
import { useState, useEffect } from 'react';
import { Plus, Boxes } from 'lucide-react';
@@ -1,4 +1,4 @@
'use client';
import { useState, useEffect } from 'react';
import { Plus, MessageSquareText, Cpu, Eye, Wrench, Check } from 'lucide-react';
@@ -1,4 +1,4 @@
'use client';
import { Plus, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
@@ -1,4 +1,4 @@
'use client';
import { useState, useEffect } from 'react';
import { Trash2, Eye, Wrench, Check } from 'lucide-react';
@@ -1,4 +1,4 @@
'use client';
import { useState } from 'react';
import {
@@ -1,4 +1,4 @@
'use client';
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
@@ -1,4 +1,4 @@
'use client';
import * as React from 'react';
import { useState, useEffect } from 'react';
@@ -1,4 +1,4 @@
'use client';
import React, { useState, useEffect, useCallback } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
@@ -1,7 +1,7 @@
'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 +32,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 +84,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() {
@@ -1,4 +1,4 @@
'use client';
import { ColumnDef } from '@tanstack/react-table';
import { MoreHorizontal } from 'lucide-react';
@@ -1,4 +1,4 @@
'use client';
import {
ColumnDef,
@@ -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';
@@ -1,4 +1,4 @@
'use client';
import { useState } from 'react';
import {
@@ -1,4 +1,4 @@
'use client';
import React, { useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+2 -2
View File
@@ -1,6 +1,6 @@
'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';
+8 -7
View File
@@ -1,4 +1,4 @@
'use client';
import HomeSidebar from '@/app/home/components/home-sidebar/HomeSidebar';
import SurveyWidget from '@/app/home/components/survey/SurveyWidget';
@@ -21,8 +21,8 @@ import {
initializeUserInfo,
initializeSystemInfo,
} from '@/app/infra/http';
import { usePathname, useRouter } from 'next/navigation';
import Link from 'next/link';
import { useNavigate } 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 +59,7 @@ export default function HomeLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const router = useRouter();
const navigate = useNavigate();
// Initialize user info if not already initialized
useEffect(() => {
@@ -75,7 +75,7 @@ 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
@@ -101,7 +101,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 +140,7 @@ function HomeLayoutInner({ children }: { children: React.ReactNode }) {
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
<BreadcrumbLink asChild>
<Link href={sectionLink}>{sectionLabel}</Link>
<Link to={sectionLink}>{sectionLabel}</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />
+1 -1
View File
@@ -1,4 +1,4 @@
'use client';
import MarketPage from '@/app/home/plugins/components/plugin-market/PluginMarketComponent';
import {
+5 -5
View File
@@ -1,7 +1,7 @@
'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 +30,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 +96,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() {
@@ -1,4 +1,4 @@
'use client';
import React, {
useState,
+2 -2
View File
@@ -1,6 +1,6 @@
'use client';
import { useSearchParams } from 'next/navigation';
import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import MCPDetailContent from './MCPDetailContent';
@@ -1,4 +1,4 @@
'use client';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React, { useState } from 'react';
import {
@@ -1,4 +1,4 @@
'use client';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -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';
+1 -1
View File
@@ -1,4 +1,4 @@
'use client';
import React, { Suspense, useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,7 +1,7 @@
'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 +13,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 +38,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 +73,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
function handleDeletePipeline() {
refreshPipelines();
router.push('/home/pipelines');
navigate('/home/pipelines');
}
// ==================== Edit Mode ====================
@@ -129,7 +129,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}
/>
</TabsContent>
@@ -152,7 +152,7 @@ export default function PipelineDetailContent({ id }: { id: string }) {
<PipelineMonitoringTab
pipelineId={id}
onNavigateToMonitoring={() => {
router.push('/home/monitoring');
navigate('/home/monitoring');
}}
/>
</TabsContent>
@@ -1,4 +1,4 @@
'use client';
import React, { useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
+2 -2
View File
@@ -1,6 +1,6 @@
'use client';
import { useSearchParams } from 'next/navigation';
import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import PipelineDetailContent from './PipelineDetailContent';
@@ -1,4 +1,4 @@
'use client';
import { useEffect } from 'react';
import PluginForm from '@/app/home/plugins/components/plugin-installed/plugin-form/PluginForm';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import {
@@ -1,4 +1,4 @@
'use client';
import React, {
createContext,
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,7 +1,7 @@
'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';
@@ -37,7 +37,7 @@ enum PluginOperationType {
const PluginInstalledComponent = forwardRef<PluginInstalledComponentRef>(
(props, ref) => {
const { t } = useTranslation();
const router = useRouter();
const navigate = useNavigate();
const { refreshPlugins } = useSidebarData();
const [pluginList, setPluginList] = useState<PluginCardVO[]>([]);
const [showOperationModal, setShowOperationModal] = useState(false);
@@ -163,7 +163,7 @@ const PluginInstalledComponent = forwardRef<PluginInstalledComponentRef>(
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) {
@@ -1,7 +1,7 @@
'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,
@@ -1,4 +1,4 @@
'use client';
import { useState, useRef, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight, Star } from 'lucide-react';
@@ -1,4 +1,4 @@
'use client';
import { useTranslation } from 'react-i18next';
import {
@@ -1,4 +1,4 @@
'use client';
import { useEffect, useState, useRef } from 'react';
import MCPCardComponent from '@/app/home/plugins/mcp-server/mcp-card/MCPCardComponent';
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
import { useTranslation } from 'react-i18next';
@@ -1,4 +1,4 @@
'use client';
import React, { useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
+4 -4
View File
@@ -1,4 +1,4 @@
'use client';
import PluginInstalledComponent, {
PluginInstalledComponentRef,
} from '@/app/home/plugins/components/plugin-installed/PluginInstalledComponent';
@@ -45,7 +45,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 } from 'react-router-dom';
import { httpClient } from '@/app/infra/http/HttpClient';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
@@ -97,7 +97,7 @@ export default function PluginConfigPage() {
function PluginListView() {
const { t } = useTranslation();
const router = useRouter();
const navigate = useNavigate();
const {
refreshPlugins,
pendingPluginInstallAction,
@@ -672,7 +672,7 @@ function PluginListView() {
{systemInfo.enable_marketplace && (
<DropdownMenuItem
onClick={() => {
router.push('/home/market');
navigate('/home/market');
}}
>
<StoreIcon className="w-4 h-4" />
+1 -1
View File
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
+7 -7
View File
@@ -1,4 +1,4 @@
'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@@ -22,12 +22,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 +40,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<AccountType | null>(null);
@@ -66,7 +66,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 +97,7 @@ export default function Login() {
.then((res) => {
if (res.token) {
localStorage.setItem('token', res.token);
router.push('/home');
navigate('/home');
}
})
.catch(() => {});
@@ -114,7 +114,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(() => {
+4 -4
View File
@@ -1,12 +1,12 @@
'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 <div className={``}></div>;
}
+1 -1
View File
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
+5 -5
View File
@@ -1,4 +1,4 @@
'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@@ -22,7 +22,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 +42,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 +63,7 @@ export default function Register() {
.checkIfInited()
.then((res) => {
if (res.initialized) {
router.push('/login');
navigate('/login');
}
})
.catch(() => {});
@@ -78,7 +78,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);
+1 -1
View File
@@ -1,4 +1,4 @@
'use client';
import React from 'react';
+5 -5
View File
@@ -1,4 +1,4 @@
'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
@@ -28,11 +28,11 @@ import {
} from '@/components/ui/form';
import { useState } from 'react';
import { httpClient } from '@/app/infra/http/HttpClient';
import { useRouter } from 'next/navigation';
import { useNavigate } from 'react-router-dom';
import { Mail, Lock, ArrowLeft } from 'lucide-react';
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';
const REGEXP_ONLY_DIGITS_AND_CHARS = /^[0-9a-zA-Z]+$/;
@@ -45,7 +45,7 @@ const formSchema = (t: (key: string) => string) =>
});
export default function ResetPassword() {
const router = useRouter();
const navigate = useNavigate();
const { t } = useTranslation();
const [isResetting, setIsResetting] = useState(false);
@@ -72,7 +72,7 @@ export default function ResetPassword() {
.resetPassword(email, recoveryKey, newPassword)
.then(() => {
toast.success(t('resetPassword.resetSuccess'));
router.push('/login');
navigate('/login');
})
.catch(() => {
toast.error(t('resetPassword.resetFailed'));
+6 -6
View File
@@ -1,7 +1,7 @@
'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 +81,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,7 +519,7 @@ export default function WizardPage() {
}
setIsSkipping(false);
setShowSkipConfirm(false);
router.push('/home');
navigate('/home');
}, [router, t]);
// ---- Render ----
@@ -1169,7 +1169,7 @@ function StepAIEngine({
function StepDone() {
const { t } = useTranslation();
const router = useRouter();
const navigate = useNavigate();
const [particles] = useState(() =>
Array.from({ length: 30 }, (_, i) => ({
@@ -1213,7 +1213,7 @@ function StepDone() {
return;
}
setIsCompleting(false);
router.push('/home/bots');
navigate('/home/bots');
}, [router, t]);
return (