chore: merge admin repo history into monorepo at admin/
git-subtree-dir: admin git-subtree-mainline:35f5084005git-subtree-split:9f1eccd2f7
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"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<UserProfile>;
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextValue | null>(null);
|
||||
|
||||
export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const [status, setStatus] = useState<AuthStatus>("loading");
|
||||
const [user, setUser] = useState<UserProfile | null>(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 (
|
||||
<AuthContext.Provider value={{ status, user, login, logout }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
const ctx = useContext(AuthContext);
|
||||
if (!ctx) throw new Error("useAuth باید داخل AuthProvider استفاده بشه");
|
||||
return ctx;
|
||||
}
|
||||
Reference in New Issue
Block a user