"use client"; import { createContext, useCallback, useContext, useEffect, useState, ReactNode, } from "react"; import { tokenStore } from "./token-store"; import { UserProfile, verifyOtp as apiVerifyOtp, getProfileMe, ApiError } from "./api"; type AuthStatus = "loading" | "guest" | "not-admin" | "authenticated"; interface AuthContextValue { status: AuthStatus; user: UserProfile | null; login: (phone: string, otp: string) => Promise; logout: () => void; } const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const [status, setStatus] = useState("loading"); const [user, setUser] = useState(null); const bootstrap = useCallback(async () => { const access = tokenStore.getAccess(); if (!access) { setStatus("guest"); return; } try { const profile = await getProfileMe(); if (!profile.user.is_admin) { setUser(profile.user); setStatus("not-admin"); return; } setUser(profile.user); setStatus("authenticated"); } catch { tokenStore.clear(); setStatus("guest"); } }, []); useEffect(() => { // eslint-disable-next-line react-hooks/set-state-in-effect bootstrap(); }, [bootstrap]); const login = useCallback(async (phone: string, otp: string) => { const data = await apiVerifyOtp(phone, otp); tokenStore.set(data.tokens.access_token, data.tokens.refresh_token); if (!data.user.is_admin) { setUser(data.user); setStatus("not-admin"); // توکن رو نگه می‌داریم نه، پاک می‌کنیم چون این پنل فقط برای ادمین‌هاست tokenStore.clear(); throw new ApiError("این حساب دسترسی ادمین نداره", 403); } setUser(data.user); setStatus("authenticated"); return data.user; }, []); const logout = useCallback(() => { tokenStore.clear(); setUser(null); setStatus("guest"); }, []); return ( {children} ); } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth باید داخل AuthProvider استفاده بشه"); return ctx; }