| | import React, { createContext, useContext, useState, useEffect } from "react"; |
| | import { signInWithPopup, signOut as firebaseSignOut } from "firebase/auth"; |
| | import { auth, googleProvider } from "@/config/firebase"; |
| | import { getCurrentUser, firebaseLogin, requestOTP, verifyOTP, logout as apiLogout } from "@/services/auth"; |
| |
|
| | const AuthContext = createContext(null); |
| |
|
| | export function AuthProvider({ children }) { |
| | const [user, setUser] = useState(null); |
| | const [loading, setLoading] = useState(true); |
| | const [token, setToken] = useState(localStorage.getItem("auth_token")); |
| |
|
| | useEffect(() => { |
| | |
| | if (token) { |
| | checkAuth(); |
| | } else { |
| | setLoading(false); |
| | } |
| | }, [token]); |
| |
|
| | const checkAuth = async () => { |
| | try { |
| | const userData = await getCurrentUser(); |
| | setUser(userData); |
| | } catch (error) { |
| | |
| | localStorage.removeItem("auth_token"); |
| | setToken(null); |
| | setUser(null); |
| | } finally { |
| | setLoading(false); |
| | } |
| | }; |
| |
|
| | const handleFirebaseLogin = async () => { |
| | try { |
| | const result = await signInWithPopup(auth, googleProvider); |
| | const idToken = await result.user.getIdToken(); |
| | const response = await firebaseLogin(idToken); |
| | handleAuthCallback(response.token); |
| | } catch (error) { |
| | if (error.code === 'auth/popup-closed' || error.code === 'auth/cancelled-popup-request') { |
| | |
| | return; |
| | } |
| | console.error("Firebase login error:", error); |
| | throw new Error(error.message || "Firebase authentication failed"); |
| | } |
| | }; |
| |
|
| | const handleOTPRequest = async (email) => { |
| | try { |
| | await requestOTP(email); |
| | } catch (error) { |
| | console.error("OTP request error:", error); |
| | throw error; |
| | } |
| | }; |
| |
|
| | const handleOTPVerify = async (email, otp) => { |
| | try { |
| | const response = await verifyOTP(email, otp); |
| | handleAuthCallback(response.token); |
| | } catch (error) { |
| | console.error("OTP verify error:", error); |
| | throw error; |
| | } |
| | }; |
| |
|
| | const handleLogout = async () => { |
| | try { |
| | |
| | if (auth.currentUser) { |
| | await firebaseSignOut(auth); |
| | } |
| | await apiLogout(); |
| | } catch (error) { |
| | console.error("Logout error:", error); |
| | } finally { |
| | localStorage.removeItem("auth_token"); |
| | setToken(null); |
| | setUser(null); |
| | } |
| | }; |
| |
|
| | const handleAuthCallback = (newToken) => { |
| | localStorage.setItem("auth_token", newToken); |
| | setToken(newToken); |
| | checkAuth(); |
| | }; |
| |
|
| | const value = { |
| | user, |
| | token, |
| | loading, |
| | firebaseLogin: handleFirebaseLogin, |
| | requestOTP: handleOTPRequest, |
| | verifyOTP: handleOTPVerify, |
| | logout: handleLogout, |
| | handleAuthCallback, |
| | isAuthenticated: !!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 an AuthProvider"); |
| | } |
| | return context; |
| | } |
| |
|