feat: 前端添加user状态管理

This commit is contained in:
2025-12-17 15:36:22 +08:00
parent f69d79a0ff
commit 86086a7054
3 changed files with 70 additions and 12 deletions

View File

@@ -0,0 +1,25 @@
'use client';
import { useEffect } from 'react';
import { useUserStore } from '@/store/useUserStore';
import { User } from '@/lib/types/user';
export function ClientProvider({
initialUser,
children,
}: {
initialUser: User | null;
children: React.ReactNode;
}) {
const setUser = useUserStore((state) => state.setUser);
const setInitialized = useUserStore((state) => state.setInitialized);
useEffect(() => {
if (initialUser) {
setUser(initialUser);
}
setInitialized();
}, [initialUser, setUser, setInitialized]);
return <>{children}</>;
}

View File

@@ -3,6 +3,8 @@ import "./globals.css";
import { ThemeProvider } from "../components/theme-provider"; import { ThemeProvider } from "../components/theme-provider";
import { metadata } from "./config/metadata"; import { metadata } from "./config/metadata";
import { Toaster } from "sonner"; import { Toaster } from "sonner";
import { UserAPI } from "@/lib/api/server";
import { ClientProvider } from "./ClientProvider";
const geistSans = Geist({ const geistSans = Geist({
variable: "--font-geist-sans", variable: "--font-geist-sans",
@@ -16,17 +18,20 @@ const geistMono = Geist_Mono({
export { metadata }; export { metadata };
export default function RootLayout({ export default async function RootLayout({
children, children,
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
const user = await UserAPI.me().catch(() => null);
return ( return (
<html lang="en" suppressHydrationWarning> <html lang="en" suppressHydrationWarning>
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`} className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`}
suppressHydrationWarning suppressHydrationWarning
> >
<ClientProvider initialUser={user}>
<ThemeProvider <ThemeProvider
attribute="class" attribute="class"
defaultTheme="system" defaultTheme="system"
@@ -38,6 +43,7 @@ export default function RootLayout({
<Toaster /> <Toaster />
</main> </main>
</ThemeProvider> </ThemeProvider>
</ClientProvider>
</body> </body>
</html> </html>
); );

View File

@@ -0,0 +1,27 @@
// store/useUserStore.ts
import { User } from '@/lib/types/user';
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
interface UserState {
user: User | null;
isLoading: boolean;
initialized: boolean;
// Actions
setInitialized: () => void;
setUser: (user: User | null) => void;
clearUser: () => void;
}
export const useUserStore = create<UserState>()(
devtools((set, get) => ({
user: null,
isLoading: false,
initialized: false,
setInitialized: () => set({ initialized: true }),
setUser: (user) => set({ user, isLoading: false }),
clearUser: () => set({ user: null }),
}))
);