| "use client"; |
|
|
| import * as React from "react"; |
| import { useRouter } from "next/navigation"; |
|
|
| interface User { |
| email: string; |
| fullName: string; |
| isPremium: boolean; |
| } |
|
|
| interface AuthContextType { |
| user: User | null; |
| token: string | null; |
| isLoading: boolean; |
| logout: () => void; |
| refreshAuth: () => void; |
| } |
|
|
| const AuthContext = React.createContext<AuthContextType | undefined>(undefined); |
|
|
| |
| |
| |
| |
| export function AuthProvider({ children }: { children: React.ReactNode }) { |
| const [user, setUser] = React.useState<User | null>(null); |
| const [token, setToken] = React.useState<string | null>(null); |
| const [isLoading, setIsLoading] = React.useState(true); |
| const router = useRouter(); |
|
|
| |
| const decodeToken = React.useCallback((jwt: string): User | null => { |
| try { |
| const payload = JSON.parse(window.atob(jwt.split(".")[1])); |
| return { |
| email: payload.sub, |
| fullName: payload.full_name || payload.sub.split('@')[0], |
| isPremium: payload.is_premium === true, |
| }; |
| } catch { |
| return null; |
| } |
| }, []); |
|
|
| |
| const refreshAuth = React.useCallback(() => { |
| |
| if (typeof window === "undefined") return; |
|
|
| const storedToken = localStorage.getItem("token"); |
|
|
| if (storedToken) { |
| const decodedUser = decodeToken(storedToken); |
| if (decodedUser) { |
| setUser(decodedUser); |
| setToken(storedToken); |
| } else { |
| |
| localStorage.removeItem("token"); |
| setUser(null); |
| setToken(null); |
| } |
| } else { |
| setUser(null); |
| setToken(null); |
| } |
| setIsLoading(false); |
| }, [decodeToken]); |
|
|
| |
| React.useEffect(() => { |
| refreshAuth(); |
| }, [refreshAuth]); |
|
|
| |
| const logout = React.useCallback(() => { |
| localStorage.removeItem("token"); |
| setToken(null); |
| setUser(null); |
| router.push("/login"); |
| }, [router]); |
|
|
| |
| const value = React.useMemo(() => ({ |
| user, |
| token, |
| isLoading, |
| logout, |
| refreshAuth |
| }), [user, token, isLoading, logout, refreshAuth]); |
|
|
| return ( |
| <AuthContext.Provider value={value}> |
| {children} |
| </AuthContext.Provider> |
| ); |
| } |
|
|
| export function useAuth() { |
| const context = React.useContext(AuthContext); |
| if (context === undefined) { |
| throw new Error("useAuth must be used within an AuthProvider"); |
| } |
| return context; |
| } |
|
|