Spaces:
Running
Running
import { createContext, useContext, useState, useEffect, ReactNode } from "react"; | |
import { AuthUser, AuthSeller } from "@/types"; | |
interface AuthContextType { | |
user: AuthUser | null; | |
seller: AuthSeller | null; | |
token: string | null; | |
userType: 'user' | 'seller' | 'admin' | null; | |
login: (token: string, userData: AuthUser) => void; | |
sellerLogin: (token: string, sellerData: AuthSeller) => void; | |
adminLogin: () => void; | |
logout: () => void; | |
isAuthenticated: boolean; | |
isLoading: boolean; | |
} | |
const AuthContext = createContext<AuthContextType | undefined>(undefined); | |
export function AuthProvider({ children }: { children: ReactNode }) { | |
const [user, setUser] = useState<AuthUser | null>(null); | |
const [seller, setSeller] = useState<AuthSeller | null>(null); | |
const [token, setToken] = useState<string | null>(null); | |
const [userType, setUserType] = useState<'user' | 'seller' | 'admin' | null>(null); | |
const [isLoading, setIsLoading] = useState<boolean>(true); | |
useEffect(() => { | |
const verifyToken = async () => { | |
const savedToken = localStorage.getItem('token'); | |
if (savedToken) { | |
try { | |
// Verify token with backend | |
const response = await fetch('/api/auth/verify', { | |
headers: { | |
'Authorization': `Bearer ${savedToken}`, | |
}, | |
}); | |
if (response.ok) { | |
const data = await response.json(); | |
setToken(savedToken); | |
setUserType(data.userType); | |
if (data.user) { | |
setUser(data.user); | |
localStorage.setItem('user', JSON.stringify(data.user)); | |
} else if (data.seller) { | |
setSeller(data.seller); | |
localStorage.setItem('seller', JSON.stringify(data.seller)); | |
} | |
localStorage.setItem('userType', data.userType); | |
} else { | |
// Token is invalid or expired, clear everything | |
logout(); | |
} | |
} catch (error) { | |
// Network error or other issues, clear auth state | |
console.error('Token verification failed:', error); | |
logout(); | |
} | |
} | |
// Set loading to false after token verification completes | |
setIsLoading(false); | |
}; | |
verifyToken(); | |
}, []); | |
const login = (token: string, userData: AuthUser) => { | |
setToken(token); | |
setUser(userData); | |
setUserType('user'); | |
localStorage.setItem('token', token); | |
localStorage.setItem('user', JSON.stringify(userData)); | |
localStorage.setItem('userType', 'user'); | |
}; | |
const sellerLogin = (token: string, sellerData: AuthSeller) => { | |
setToken(token); | |
setSeller(sellerData); | |
setUserType('seller'); | |
localStorage.setItem('token', token); | |
localStorage.setItem('seller', JSON.stringify(sellerData)); | |
localStorage.setItem('userType', 'seller'); | |
}; | |
const adminLogin = () => { | |
setUserType('admin'); | |
localStorage.setItem('userType', 'admin'); | |
}; | |
const logout = () => { | |
setToken(null); | |
setUser(null); | |
setSeller(null); | |
setUserType(null); | |
localStorage.removeItem('token'); | |
localStorage.removeItem('user'); | |
localStorage.removeItem('seller'); | |
localStorage.removeItem('userType'); | |
}; | |
const isAuthenticated = Boolean(token || userType === 'admin'); | |
return ( | |
<AuthContext.Provider value={{ | |
user, | |
seller, | |
token, | |
userType, | |
login, | |
sellerLogin, | |
adminLogin, | |
logout, | |
isAuthenticated, | |
isLoading, | |
}}> | |
{children} | |
</AuthContext.Provider> | |
); | |
} | |
export function useAuth() { | |
const context = useContext(AuthContext); | |
if (context === undefined) { | |
throw new Error('useAuth must be used within an AuthProvider'); | |
} | |
return context; | |
} | |