"use client"; import React, { createContext, useContext, useState, useEffect } from "react"; import { useRouter, usePathname } from "next/navigation"; import { UserData } from "@/types/auth"; import { API_URL } from "@/lib/auth"; interface AuthContextType { token: string | null; setToken: (token: string | null) => void; logout: () => void; isLoading: boolean; user: UserData | null; fetchUser: () => Promise; } const AuthContext = createContext(undefined); // Cookie utility functions const getCookie = (name: string): string | null => { if (typeof document === "undefined") return null; const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) { return parts.pop()?.split(";").shift() || null; } return null; }; const setCookie = ( name: string, value: string | null, days: number = 7 ): void => { if (typeof document === "undefined") return; if (value === null) { document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Strict; Secure`; } else { const expires = new Date(); expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/; SameSite=Strict; Secure`; } }; export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [token, setTokenState] = useState(null); const [isLoading, setIsLoading] = useState(true); const [user, setUser] = useState(null); const router = useRouter(); const pathname = usePathname(); const setToken = (newToken: string | null) => { setTokenState(newToken); setCookie("authToken", newToken); }; // Fetch user info from API const fetchUser = async () => { if (!token) return; try { const res = await fetch(`${API_URL}/me/profile/`, { headers: { Authorization: `Bearer ${token}`, }, }); if (!res.ok) { throw new Error("Failed to fetch user info"); } const data: UserData = await res.json(); setUser(data); } catch (error) { console.error("Error fetching user:", error); setUser(null); logout(); } }; useEffect(() => { const initializeAuth = async () => { const storedToken = getCookie("authToken"); if (storedToken) { setTokenState(storedToken); if ( pathname === "/" || pathname === "/login" || pathname === "/register" ) { router.replace("/home"); } // Fetch user info when token is found await fetchUser(); } else { const publicPages = ["/", "/login", "/register"]; if (!publicPages.includes(pathname)) { router.replace("/"); } } setIsLoading(false); }; initializeAuth(); }, [pathname, router]); const logout = () => { setTokenState(null); setUser(null); setCookie("authToken", null); router.replace("/login"); }; return ( {children} ); }; export const useAuth = () => { const context = useContext(AuthContext); if (!context) { throw new Error("useAuth must be used within an AuthProvider"); } return context; };