feat: add captcha support for user login and enhance user profile page

- Refactored userLogin function to include captcha handling.
- Introduced getCaptchaConfig API to fetch captcha configuration.
- Added Captcha component to handle different captcha providers (hCaptcha, reCaptcha, Turnstile).
- Updated LoginForm component to integrate captcha verification.
- Created UserProfile component to display user information with avatar.
- Implemented getUserByUsername API to fetch user details by username.
- Removed deprecated LoginRequest interface from user model.
- Enhanced navbar and layout with animation effects.
- Removed unused user page component and added dynamic user profile routing.
- Updated localization files to include captcha-related messages.
- Improved Gravatar component for better avatar handling.
This commit is contained in:
2025-09-10 21:15:36 +08:00
parent a7da023b1e
commit 4781d81869
28 changed files with 1048 additions and 701 deletions

View File

@ -5,6 +5,7 @@ import { usePathname } from 'next/navigation'
import { Navbar } from '@/components/layout/navbar'
import { BackgroundProvider } from '@/contexts/background-context'
import Footer from '@/components/layout/footer'
import config from '@/config'
export default function RootLayout({
children,
@ -14,25 +15,18 @@ export default function RootLayout({
const pathname = usePathname()
return (
<>
<header className="fixed top-0 left-0 w-full z-50 bg-white/80 dark:bg-slate-900/80 backdrop-blur flex justify-center border-b border-slate-200 dark:border-slate-800">
<motion.nav
initial={{ y: -64, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: config.animationDurationSecond, ease: "easeOut" }}>
<header className="fixed top-0 left-0 h-16 w-full z-50 bg-white/80 dark:bg-slate-900/80 backdrop-blur flex justify-center border-b border-slate-200 dark:border-slate-800">
<Navbar />
</header>
<motion.main
key={pathname}
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{
type: 'tween',
ease: 'easeOut',
duration: 0.30,
}}
className="pt-16"
>
<BackgroundProvider>
<div className='container mx-auto px-4 sm:px-6 lg:px-10 max-w-7xl'>{children}</div>
</BackgroundProvider>
</motion.main>
</motion.nav>
<BackgroundProvider>
<div className='container mx-auto pt-16 px-4 sm:px-6 lg:px-10 max-w-7xl'>{children}</div>
</BackgroundProvider>
<Footer />
</>
)

View File

@ -1,8 +0,0 @@
export default function Page() {
return (
<div>
<h1>Page Title</h1>
<p>This is the User content.</p>
</div>
)
}

View File

@ -0,0 +1,27 @@
"use client"
import { getUserByUsername } from "@/api/user";
import { UserPage } from "@/components/user";
import { User } from "@/models/user";
import { useParams } from "next/navigation";
import { useEffect, useState } from "react";
export default function Page() {
const { username } = useParams() as { username: string };
const [user,setUser] = useState<User | null>(null);
useEffect(() => {
getUserByUsername(username).then(res => {
setUser(res.data);
});
},[username]);
if (!user) {
return <div>Loading...</div>;
}
return (
<div>
<UserPage user={user} />
</div>
)
}