[优化] 格式化

This commit is contained in:
ryan
2026-05-30 13:15:20 +08:00
parent 28b1305906
commit 9ec3d5b42d
110 changed files with 29155 additions and 7642 deletions
@@ -1,37 +1,37 @@
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { type ReactNode, useState } from 'react';
import { AuthProvider } from '@/components/providers/auth-provider';
import { ThemeProvider } from '@/components/providers/theme-provider';
interface AppProvidersProps {
children: ReactNode;
}
export function AppProviders({ children }: AppProvidersProps) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 1,
staleTime: 30_000,
},
mutations: {
retry: 0,
},
},
}),
);
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<AuthProvider>{children}</AuthProvider>
</ThemeProvider>
</QueryClientProvider>
);
}
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { type ReactNode, useState } from 'react';
import { AuthProvider } from '@/components/providers/auth-provider';
import { ThemeProvider } from '@/components/providers/theme-provider';
interface AppProvidersProps {
children: ReactNode;
}
export function AppProviders({ children }: AppProvidersProps) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 1,
staleTime: 30_000,
},
mutations: {
retry: 0,
},
},
}),
);
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<AuthProvider>{children}</AuthProvider>
</ThemeProvider>
</QueryClientProvider>
);
}
@@ -1,89 +1,92 @@
'use client';
import {
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { logout as logoutRequest, getCurrentUser } from '@/features/auth/api/auth';
import type { AuthUser } from '@/types/auth';
interface AuthContextValue {
user: AuthUser | null;
isLoading: boolean;
isAuthenticated: boolean;
refreshUser: () => Promise<AuthUser | null>;
setUser: (user: AuthUser | null) => void;
logout: () => Promise<void>;
}
const AuthContext = createContext<AuthContextValue | null>(null);
interface AuthProviderProps {
children: ReactNode;
}
export function AuthProvider({ children }: AuthProviderProps) {
const [user, setUserState] = useState<AuthUser | null>(null);
const [isLoading, setIsLoading] = useState(true);
const refreshUser = useCallback(async () => {
try {
const nextUser = await getCurrentUser();
setUserState(nextUser);
return nextUser;
} catch {
setUserState(null);
return null;
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
void refreshUser();
}, [refreshUser]);
const setUser = useCallback((nextUser: AuthUser | null) => {
setUserState(nextUser);
setIsLoading(false);
}, []);
const logout = useCallback(async () => {
try {
await logoutRequest();
} finally {
setUserState(null);
setIsLoading(false);
}
}, []);
const value = useMemo(
() => ({
user,
isLoading,
isAuthenticated: user !== null,
refreshUser,
setUser,
logout,
}),
[isLoading, logout, refreshUser, setUser, user],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
}
'use client';
import {
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import {
logout as logoutRequest,
getCurrentUser,
} from '@/features/auth/api/auth';
import type { AuthUser } from '@/types/auth';
interface AuthContextValue {
user: AuthUser | null;
isLoading: boolean;
isAuthenticated: boolean;
refreshUser: () => Promise<AuthUser | null>;
setUser: (user: AuthUser | null) => void;
logout: () => Promise<void>;
}
const AuthContext = createContext<AuthContextValue | null>(null);
interface AuthProviderProps {
children: ReactNode;
}
export function AuthProvider({ children }: AuthProviderProps) {
const [user, setUserState] = useState<AuthUser | null>(null);
const [isLoading, setIsLoading] = useState(true);
const refreshUser = useCallback(async () => {
try {
const nextUser = await getCurrentUser();
setUserState(nextUser);
return nextUser;
} catch {
setUserState(null);
return null;
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
void refreshUser();
}, [refreshUser]);
const setUser = useCallback((nextUser: AuthUser | null) => {
setUserState(nextUser);
setIsLoading(false);
}, []);
const logout = useCallback(async () => {
try {
await logoutRequest();
} finally {
setUserState(null);
setIsLoading(false);
}
}, []);
const value = useMemo(
() => ({
user,
isLoading,
isAuthenticated: user !== null,
refreshUser,
setUser,
logout,
}),
[isLoading, logout, refreshUser, setUser, user],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
}
@@ -1,107 +1,109 @@
'use client';
import {
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import {
isThemeMode,
resolveTheme,
THEME_MEDIA_QUERY,
THEME_STORAGE_KEY,
type ResolvedTheme,
type ThemeMode,
} from '@/lib/theme/theme';
interface ThemeContextValue {
themeMode: ThemeMode;
resolvedTheme: ResolvedTheme;
setThemeMode: (mode: ThemeMode) => void;
}
const ThemeContext = createContext<ThemeContextValue | null>(null);
interface ThemeProviderProps {
children: ReactNode;
}
function getSystemPreference() {
return window.matchMedia(THEME_MEDIA_QUERY).matches;
}
function applyTheme(mode: ThemeMode) {
const resolvedTheme = resolveTheme(mode, getSystemPreference());
const root = document.documentElement;
root.dataset.themeMode = mode;
root.dataset.theme = resolvedTheme;
root.style.colorScheme = resolvedTheme;
window.localStorage.setItem(THEME_STORAGE_KEY, mode);
return resolvedTheme;
}
export function ThemeProvider({ children }: ThemeProviderProps) {
const [themeMode, setThemeModeState] = useState<ThemeMode>('system');
const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>('dark');
useEffect(() => {
const root = document.documentElement;
const domThemeMode = root.dataset.themeMode;
const nextThemeMode = isThemeMode(domThemeMode) ? domThemeMode : 'system';
const nextResolvedTheme = applyTheme(nextThemeMode);
setThemeModeState(nextThemeMode);
setResolvedTheme(nextResolvedTheme);
}, []);
useEffect(() => {
const mediaQuery = window.matchMedia(THEME_MEDIA_QUERY);
const handleChange = () => {
if (themeMode !== 'system') {
return;
}
setResolvedTheme(applyTheme('system'));
};
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}, [themeMode]);
const setThemeMode = useCallback((mode: ThemeMode) => {
setThemeModeState(mode);
setResolvedTheme(applyTheme(mode));
}, []);
const value = useMemo(
() => ({
themeMode,
resolvedTheme,
setThemeMode,
}),
[resolvedTheme, setThemeMode, themeMode],
);
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
}
'use client';
import {
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import {
isThemeMode,
resolveTheme,
THEME_MEDIA_QUERY,
THEME_STORAGE_KEY,
type ResolvedTheme,
type ThemeMode,
} from '@/lib/theme/theme';
interface ThemeContextValue {
themeMode: ThemeMode;
resolvedTheme: ResolvedTheme;
setThemeMode: (mode: ThemeMode) => void;
}
const ThemeContext = createContext<ThemeContextValue | null>(null);
interface ThemeProviderProps {
children: ReactNode;
}
function getSystemPreference() {
return window.matchMedia(THEME_MEDIA_QUERY).matches;
}
function applyTheme(mode: ThemeMode) {
const resolvedTheme = resolveTheme(mode, getSystemPreference());
const root = document.documentElement;
root.dataset.themeMode = mode;
root.dataset.theme = resolvedTheme;
root.style.colorScheme = resolvedTheme;
window.localStorage.setItem(THEME_STORAGE_KEY, mode);
return resolvedTheme;
}
export function ThemeProvider({ children }: ThemeProviderProps) {
const [themeMode, setThemeModeState] = useState<ThemeMode>('system');
const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>('dark');
useEffect(() => {
const root = document.documentElement;
const domThemeMode = root.dataset.themeMode;
const nextThemeMode = isThemeMode(domThemeMode) ? domThemeMode : 'system';
const nextResolvedTheme = applyTheme(nextThemeMode);
setThemeModeState(nextThemeMode);
setResolvedTheme(nextResolvedTheme);
}, []);
useEffect(() => {
const mediaQuery = window.matchMedia(THEME_MEDIA_QUERY);
const handleChange = () => {
if (themeMode !== 'system') {
return;
}
setResolvedTheme(applyTheme('system'));
};
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}, [themeMode]);
const setThemeMode = useCallback((mode: ThemeMode) => {
setThemeModeState(mode);
setResolvedTheme(applyTheme(mode));
}, []);
const value = useMemo(
() => ({
themeMode,
resolvedTheme,
setThemeMode,
}),
[resolvedTheme, setThemeMode, themeMode],
);
return (
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
}