feat: add email verification and password reset functionality

- Introduced environment variables for database and email configurations.
- Implemented email verification code generation and validation.
- Added password reset feature with email verification.
- Updated user registration and profile management APIs.
- Refactored user security settings to include email and password updates.
- Enhanced console layout with internationalization support.
- Removed deprecated settings page and integrated global settings.
- Added new reset password page and form components.
- Updated localization files for new features and translations.
This commit is contained in:
2025-09-23 00:33:34 +08:00
parent c9db6795b2
commit b0b32c93d1
32 changed files with 888 additions and 345 deletions

View File

@ -0,0 +1,5 @@
import GlobalPage from "@/components/console/global";
export default function Page() {
return <GlobalPage />;
}

View File

@ -11,12 +11,14 @@ import { useEffect, useState } from "react"
import { useAuth } from "@/contexts/auth-context"
import { sidebarData, SidebarItem } from "@/components/console/data"
import { usePathname } from "next/navigation"
import { useTranslations } from "next-intl"
export default function ConsoleLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const t = useTranslations("Console")
const { user } = useAuth();
const [title, setTitle] = useState("Title");
const toLogin = useToLogin();
@ -27,12 +29,12 @@ export default function ConsoleLayout({
useEffect(() => {
const currentItem = sideBarItems.find(item => item.url === pathname);
if (currentItem) {
setTitle(currentItem.title);
document.title = `${currentItem.title} - 控制台`;
setTitle(t(currentItem.title));
document.title = `${t(currentItem.title)} - 控制台`;
} else {
setTitle("Title");
}
}, [pathname, sideBarItems]);
}, [pathname, sideBarItems, t]);
useEffect(() => {
if (!user) {

View File

@ -1,5 +0,0 @@
import SettingPage from "@/components/console/setting";
export default function Page() {
return <SettingPage />;
}

View File

@ -0,0 +1,25 @@
import { ResetPasswordForm } from "@/components/reset-password/reset-password-form";
import config from "@/config";
import Image from "next/image";
export default function Page() {
return (
<div className="bg-muted flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
<div className="flex w-full max-w-sm flex-col gap-6">
<a href="#" className="flex items-center gap-3 self-center font-bold text-2xl">
<div className="flex size-10 items-center justify-center rounded-full overflow-hidden border-2 border-gray-300 dark:border-gray-600">
<Image
src={config.metadata.icon}
alt="Logo"
width={40}
height={40}
className="rounded-full object-cover"
/>
</div>
<span className="font-bold text-2xl">{config.metadata.name}</span>
</a>
<ResetPasswordForm />
</div>
</div>
)
}