'use client'; import React, { createContext, useContext, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Session, User } from '@supabase/supabase-js'; import supabase from './supabase'; // 定义用户类型 export type AuthUser = User | null; // 定义验证上下文类型 export type AuthContextType = { user: AuthUser; session: Session | null; isLoading: boolean; signIn: (email: string, password: string) => Promise<{ error?: unknown }>; signInWithGoogle: () => Promise<{ error?: unknown }>; signInWithGitHub: () => Promise<{ error?: unknown }>; signUp: (email: string, password: string) => Promise; signOut: () => Promise; }; // 创建验证上下文 const AuthContext = createContext(undefined); // 验证提供者组件 export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [user, setUser] = useState(null); const [session, setSession] = useState(null); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); // 初始化验证状态 useEffect(() => { const getSession = async () => { setIsLoading(true); try { // 尝试从Supabase获取会话 const { data: { session }, error } = await supabase.auth.getSession(); if (error) { console.error('Error getting session:', error); return; } // 打印会话信息,帮助调试 console.log('Supabase session loaded:', session ? 'Found' : 'Not found'); if (session) { console.log('User authenticated:', session.user.email); if (session.expires_at) { console.log('Session expires at:', new Date(session.expires_at * 1000).toLocaleString()); } } setSession(session); setUser(session?.user || null); } catch (error) { console.error('Unexpected error during getSession:', error); } finally { setIsLoading(false); } }; getSession(); // 监听验证状态变化 const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { console.log('Auth state changed, event:', _event); console.log('New session:', session ? 'Valid' : 'None'); setSession(session); setUser(session?.user || null); }); // 清理函数 return () => { subscription.unsubscribe(); }; }, []); // 登录函数 const signIn = async (email: string, password: string) => { setIsLoading(true); try { console.log('尝试登录:', { email }); // 尝试通过Supabase登录 const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { console.error('登录出错:', error); return { error }; } // 登录成功,设置会话和用户信息 console.log('登录成功,用户信息:', data.user?.email); setSession(data.session); setUser(data.user); // 使用硬重定向代替router.push,确保页面完全刷新 console.log('准备重定向到分析页面'); // 添加短暂延时确保状态已更新,然后重定向 setTimeout(() => { window.location.href = '/analytics'; }, 100); return {}; } catch (error) { console.error('登录过程出错:', error); return { error }; } finally { setIsLoading(false); } }; // Google登录函数 const signInWithGoogle = async () => { setIsLoading(true); try { // 尝试通过Supabase登录Google const { error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${window.location.origin}/auth/callback`, queryParams: { access_type: 'offline', prompt: 'consent', } }, }); if (error) { console.error('Google登录出错:', error); return { error }; } return {}; // Return empty object when successful } catch (error) { console.error('Google登录过程出错:', error); return { error }; } finally { setIsLoading(false); } }; // GitHub登录函数 const signInWithGitHub = async () => { setIsLoading(true); try { // 尝试通过Supabase登录GitHub const { error } = await supabase.auth.signInWithOAuth({ provider: 'github', options: { redirectTo: `${window.location.origin}/auth/callback`, }, }); if (error) { console.error('GitHub login error:', error); return { error }; } return {}; // Return empty object when successful } catch (error) { console.error('GitHub login process error:', error); return { error }; } finally { setIsLoading(false); } }; // 注册函数 const signUp = async (email: string, password: string) => { setIsLoading(true); try { // 尝试通过Supabase注册 const { error } = await supabase.auth.signUp({ email, password, options: { emailRedirectTo: `${window.location.origin}/auth/callback`, } }); if (error) { console.error('注册出错:', error); throw error; } // 注册成功后跳转到登录页面并显示确认消息 router.push('/login?message=Registration successful! Please check your email to verify your account before logging in.'); } catch (error) { console.error('注册过程出错:', error); throw error; } finally { setIsLoading(false); } }; // 登出函数 const signOut = async () => { setIsLoading(true); try { // 尝试通过Supabase登出 const { error } = await supabase.auth.signOut(); if (error) { console.error('登出出错:', error); throw error; } setSession(null); setUser(null); router.push('/login'); } catch (error) { console.error('登出过程出错:', error); throw error; } finally { setIsLoading(false); } }; const contextValue: AuthContextType = { user, session, isLoading, signIn, signInWithGoogle, signInWithGitHub, signUp, signOut, }; return ( {children} ); }; // 自定义钩子 export const useAuth = () => { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }; // 受保护路由组件 export const ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { user, isLoading } = useAuth(); const router = useRouter(); useEffect(() => { if (!isLoading && !user) { router.push('/login'); } }, [user, isLoading, router]); if (isLoading) { return (

加载中...

); } if (!user) { return null; } return <>{children}; }; export default AuthContext;