- 修复DashboardLayout中的退出登录函数,确保清除所有认证信息 - 恢复_app.tsx中的认证逻辑,确保仪表盘页面需要登录访问 - 完善退出登录流程:清除本地存储 -> 调用登出API -> 重定向到登录页面 - 添加错误边界组件提升用户体验 - 优化React水合错误处理 - 添加JWT令牌验证API - 完善各个仪表盘页面的功能和样式
104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
// 开发环境的水合错误调试工具
|
|
export const hydrationDebug = {
|
|
// 检查是否在客户端
|
|
isClient: typeof window !== 'undefined',
|
|
|
|
// 检查是否在开发环境
|
|
isDevelopment: process.env.NODE_ENV === 'development',
|
|
|
|
// 记录水合错误
|
|
logHydrationError: (error: Error, componentName?: string) => {
|
|
if (hydrationDebug.isDevelopment) {
|
|
console.group('🔧 Hydration Error Debug');
|
|
console.error('Component:', componentName || 'Unknown');
|
|
console.error('Error:', error.message);
|
|
console.error('Stack:', error.stack);
|
|
|
|
// 检查常见的水合错误原因
|
|
const commonCauses = [
|
|
'Server and client rendered different content',
|
|
'useEffect running on server',
|
|
'Date/time differences',
|
|
'Random values',
|
|
'Browser-specific APIs',
|
|
'localStorage/sessionStorage access',
|
|
'Window object access'
|
|
];
|
|
|
|
console.warn('Common causes of hydration errors:');
|
|
commonCauses.forEach((cause, index) => {
|
|
console.warn(`${index + 1}. ${cause}`);
|
|
});
|
|
|
|
console.groupEnd();
|
|
}
|
|
},
|
|
|
|
// 安全地访问浏览器 API
|
|
safeWindowAccess: <T>(callback: () => T, fallback: T): T => {
|
|
if (hydrationDebug.isClient) {
|
|
try {
|
|
return callback();
|
|
} catch (error) {
|
|
console.warn('Safe window access failed:', error);
|
|
return fallback;
|
|
}
|
|
}
|
|
return fallback;
|
|
},
|
|
|
|
// 安全地访问 localStorage
|
|
safeLocalStorage: {
|
|
getItem: (key: string): string | null => {
|
|
return hydrationDebug.safeWindowAccess(
|
|
() => localStorage.getItem(key),
|
|
null
|
|
);
|
|
},
|
|
setItem: (key: string, value: string): void => {
|
|
hydrationDebug.safeWindowAccess(
|
|
() => localStorage.setItem(key, value),
|
|
undefined
|
|
);
|
|
},
|
|
removeItem: (key: string): void => {
|
|
hydrationDebug.safeWindowAccess(
|
|
() => localStorage.removeItem(key),
|
|
undefined
|
|
);
|
|
}
|
|
},
|
|
|
|
// 检查环境变量是否在客户端和服务器端一致
|
|
checkEnvConsistency: () => {
|
|
if (hydrationDebug.isDevelopment && hydrationDebug.isClient) {
|
|
const clientEnv = {
|
|
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
|
|
NODE_ENV: process.env.NODE_ENV,
|
|
};
|
|
|
|
console.group('🔍 Environment Variables Check');
|
|
console.log('Client-side environment variables:', clientEnv);
|
|
|
|
// 检查是否有未定义的环境变量
|
|
Object.entries(clientEnv).forEach(([key, value]) => {
|
|
if (!value) {
|
|
console.warn(`⚠️ Environment variable ${key} is undefined`);
|
|
}
|
|
});
|
|
|
|
console.groupEnd();
|
|
}
|
|
}
|
|
};
|
|
|
|
// 在开发环境中自动运行环境变量检查
|
|
if (hydrationDebug.isDevelopment && hydrationDebug.isClient) {
|
|
// 延迟执行以避免在初始渲染时执行
|
|
setTimeout(() => {
|
|
hydrationDebug.checkEnvConsistency();
|
|
}, 1000);
|
|
}
|
|
|
|
export default hydrationDebug;
|