feat(web): 添加和更新其他页面

- 新增 not-found.tsx 404 页面
- 更新 profile 页面
- LoginForm 代码优化

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
charilezhou
2026-01-17 21:43:39 +08:00
parent 6ade9b68c9
commit 55dbe844af
3 changed files with 81 additions and 5 deletions

View File

@@ -1,7 +1,12 @@
'use client';
import { RefreshCw } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import { PasswordForm } from '@/components/forms/PasswordForm';
import { ProfileForm } from '@/components/forms/ProfileForm';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
@@ -9,8 +14,26 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { getUserMenusAndPermissions } from '@/services/permission.service';
import { usePermissionStore } from '@/stores';
export default function ProfilePage() {
const [isRefreshing, setIsRefreshing] = useState(false);
const setPermissionData = usePermissionStore((state) => state.setPermissionData);
const handleRefreshPermissions = async () => {
setIsRefreshing(true);
try {
const data = await getUserMenusAndPermissions();
setPermissionData(data);
toast.success('权限缓存已刷新');
} catch (error) {
toast.error(error instanceof Error ? error.message : '刷新失败');
} finally {
setIsRefreshing(false);
}
};
return (
<div className="space-y-6">
<div>
@@ -38,6 +61,21 @@ export default function ProfilePage() {
<PasswordForm />
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
</CardDescription>
</CardHeader>
<CardContent>
<Button onClick={handleRefreshPermissions} disabled={isRefreshing}>
<RefreshCw className={`mr-2 h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
{isRefreshing ? '刷新中...' : '刷新权限缓存'}
</Button>
</CardContent>
</Card>
</div>
</div>
);

View File

@@ -0,0 +1,42 @@
'use client';
import { FileQuestion } from 'lucide-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
export default function NotFoundPage() {
const router = useRouter();
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="text-center space-y-6 p-8">
<div className="flex justify-center">
<div className="rounded-full bg-primary/10 p-6">
<FileQuestion className="h-16 w-16 text-primary" />
</div>
</div>
<div className="space-y-2">
<h1 className="text-4xl font-bold tracking-tight">404</h1>
<h2 className="text-xl font-semibold text-muted-foreground">
</h2>
<p className="text-muted-foreground max-w-md mx-auto">
访
</p>
</div>
<div className="flex flex-col sm:flex-row gap-3 justify-center">
<Button variant="outline" onClick={() => router.back()}>
</Button>
<Button asChild>
<Link href="/dashboard"></Link>
</Button>
</div>
</div>
</div>
);
}

View File

@@ -3,7 +3,6 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { CaptchaScene } from '@seclusion/shared';
import { Loader2 } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
@@ -25,9 +24,6 @@ import { useAuthStore } from '@/stores';
export function LoginForm() {
const router = useRouter();
const searchParams = useSearchParams();
const redirectUri = searchParams.get('redirect') || '/dashboard';
const { setAuth } = useAuthStore();
const [isLoading, setIsLoading] = useState(false);
@@ -59,7 +55,7 @@ export function LoginForm() {
response.refreshTokenExpiresIn
);
toast.success('登录成功');
router.push(redirectUri);
// 登录成功后AuthRedirect 组件会自动处理重定向(包括权限检查)
} catch (error) {
toast.error(error instanceof Error ? error.message : '登录失败');
// 刷新验证码