'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'; import { limqRequest } from './api'; // 定义用户类型 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; } 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) => { 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 }; } setSession(data.session); setUser(data.user); router.push('/analytics'); return {}; } catch (error) { console.error('登录过程出错:', error); return { error }; } finally { setIsLoading(false); } }; // Google登录函数 const signInWithGoogle = async () => { setIsLoading(true); try { // 获取网站 URL,如果环境变量不存在则使用当前来源 const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || window.location.origin; // 尝试通过Supabase登录Google const { error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${siteUrl}/auth/callback`, }, }); 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 { // 获取网站 URL,如果环境变量不存在则使用当前来源 const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || window.location.origin; // 尝试通过Supabase登录GitHub const { error } = await supabase.auth.signInWithOAuth({ provider: 'github', options: { redirectTo: `${siteUrl}/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 { // 获取网站 URL,如果环境变量不存在则使用当前来源 const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || window.location.origin; // 尝试通过Supabase注册 const { error } = await supabase.auth.signUp({ email, password, options: { emailRedirectTo: `${siteUrl}/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;