import React, { createContext, useContext, useState, useEffect } from "react"; import { supabase } from "@/config/supabase"; import { message } from "antd"; import { useNavigate, useSearchParams, useLocation } from "react-router-dom"; const AuthContext = createContext({}); export const AuthProvider = ({ children }) => { const [searchParams, setSearchParams] = useSearchParams(); const navigate = useNavigate(); const location = useLocation(); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { //处理google登录 const hash = window.location.hash.substring(1); const hashParams = new URLSearchParams(hash); const accessToken = hashParams.get("access_token"); const refreshToken = hashParams.get("refresh_token"); if (accessToken && refreshToken) { (async () => { const { data, error } = await supabase.auth.setSession({ access_token: accessToken, refresh_token: refreshToken, }); })(); } }, [navigate]); // 监听认证状态变化 useEffect(() => { // 获取初始会话状态 const initSession = async () => { try { const { data: { session }, error, } = await supabase.auth.getSession(); setUser(session?.user ?? null); } catch (error) { console.error("Error getting session:", error); } finally { setLoading(false); } }; initSession(); // 订阅认证状态变化 const { data: { subscription }, } = supabase.auth.onAuthStateChange((_event, session) => { setUser(session?.user ?? null); }); return () => { subscription?.unsubscribe(); }; }, []); // useEffect(() => { // const redirectTo = searchParams.get("redirectTo"); // if (redirectTo) { // navigate(redirectTo); // } // }, [location.pathname]); // 邮箱密码登录 const login = async (email, password) => { try { setLoading(true); const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { message.error(error.message || "登录失败,请稍后重试"); return; } setUser(data.user); return data; } catch (error) { message.error(error.message || "登录失败,请稍后重试"); } finally { setLoading(false); } }; // Google 登录 const signInWithGoogle = async () => { try { setLoading(true); const redirectTo = searchParams.get("redirectTo"); const { data, error } = await supabase.auth.signInWithOAuth({ provider: "google", options: { redirectTo: `${window.location.origin}/login?redirectTo=${ redirectTo ?? "" }`, }, }); if (error) { message.error(error.message || "Google 登录失败,请稍后重试"); return; } return data; } catch (error) { message.error(error.message || "Google 登录失败,请稍后重试"); } finally { setLoading(false); } }; // 注册 const register = async (email, password) => { try { setLoading(true); const { data, error } = await supabase.auth.signUp({ email, password, options: { emailRedirectTo: `${window.location.origin}/auth/callback`, }, }); if (error) { throw error; } message.success("注册成功!请查收验证邮件。"); return data; } catch (error) { message.error(error.message || "注册失败"); throw error; } finally { setLoading(false); } }; // 登出 const logout = async () => { try { setLoading(true); const { error } = await supabase.auth.signOut({ scope: "local", }); if (error) { message.error(error.message || "登出失败,请稍后重试"); return; } setUser(null); message.success("已成功登出"); navigate(`/login?redirectTo=${location.pathname}`, { replace: true }); } catch (error) { message.error(error.message || "登出失败,请稍后重试"); } finally { setLoading(false); } }; const value = { user, loading, login, logout, register, signInWithGoogle, }; return {children}; }; export const useAuth = () => { const context = useContext(AuthContext); return context; };