68 lines
2.0 KiB
JavaScript
68 lines
2.0 KiB
JavaScript
import { createContext, useContext, useState, useCallback } from "react";
|
|
|
|
const AuthContext = createContext(null);
|
|
|
|
/**
|
|
* AuthProvider — глобальный контекст аутентификации.
|
|
* Хранит текущего пользователя и JWT-токен в localStorage.
|
|
* Предоставляет методы login / logout / isAuthenticated.
|
|
*/
|
|
export function AuthProvider({ children }) {
|
|
const [user, setUser] = useState(() => {
|
|
try {
|
|
const raw = localStorage.getItem("user");
|
|
return raw ? JSON.parse(raw) : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
const [token, setToken] = useState(() => localStorage.getItem("token"));
|
|
|
|
/** Сохраняет данные пользователя и токен после успешного входа. */
|
|
const login = useCallback((userData, tokenStr) => {
|
|
localStorage.setItem("user", JSON.stringify(userData));
|
|
localStorage.setItem("token", tokenStr);
|
|
setUser(userData);
|
|
setToken(tokenStr);
|
|
}, []);
|
|
|
|
/** Очищает все данные аутентификации. */
|
|
const logout = useCallback(() => {
|
|
localStorage.removeItem("user");
|
|
localStorage.removeItem("token");
|
|
setUser(null);
|
|
setToken(null);
|
|
}, []);
|
|
|
|
/** Обновляет данные пользователя в контексте и localStorage. */
|
|
const updateUser = useCallback((userData) => {
|
|
localStorage.setItem("user", JSON.stringify(userData));
|
|
setUser(userData);
|
|
}, []);
|
|
|
|
return (
|
|
<AuthContext.Provider
|
|
value={{
|
|
user,
|
|
token,
|
|
isAuthenticated: !!token,
|
|
login,
|
|
logout,
|
|
updateUser,
|
|
}}
|
|
>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
/** Хук для доступа к контексту аутентификации. */
|
|
export function useAuthContext() {
|
|
const ctx = useContext(AuthContext);
|
|
if (!ctx) {
|
|
throw new Error("useAuthContext must be used inside AuthProvider");
|
|
}
|
|
return ctx;
|
|
}
|