Files
smart-search-frontend/src/app/providers/AuthContext.tsx
2025-12-20 16:40:13 +03:00

95 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createContext, useContext, useEffect, useState } from 'react';
import { useNavigate } from "react-router-dom";
import { authApi, IAuthUser } from "@/shared/api";
import { ROUTES } from "@/shared/lib/hooks/useNavigation";
interface IAuthContext {
user: IAuthUser | null;
loading: boolean;
updateUserContext?: (newValues: Partial<IAuthContext>) => void;
}
const AuthContext = createContext<IAuthContext>({
user: null,
loading: true,
});
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
};
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<IAuthUser | null>(null);
const [loading, setLoading] = useState(true);
const navigate = useNavigate();
const validateToken = async () => {
const accessToken = window.localStorage.getItem("accessToken");
const refreshToken = window.localStorage.getItem("refreshToken");
if (!accessToken) {
// Токена нет → отправляем на регистрацию
navigate(ROUTES.REGISTER, { replace: true });
setLoading(false);
return;
}
try {
const { data } = await authApi.validateToken();
if (data.success) {
// Токен валиден
setUser(data.user);
} else if (refreshToken) {
// Токен устарел → обновляем
const { data: refreshData } = await authApi.refreshToken({ refreshToken });
if (refreshData.accessToken) {
window.localStorage.setItem("accessToken", refreshData.accessToken);
// Повторная валидация после обновления токена
const { data: validated } = await authApi.validateToken();
if (validated.success) setUser(validated.user);
} else {
// Не удалось обновить → отправляем на логин
navigate(ROUTES.LOGIN, { replace: true });
}
} else {
// Нет refresh токена → отправляем на логин
navigate(ROUTES.LOGIN, { replace: true });
}
} catch (err) {
/* eslint-disable */
console.error('Ошибка при проверке токена', err);
/* eslint-enable */
navigate(ROUTES.LOGIN, { replace: true });
} finally {
setLoading(false);
}
};
useEffect(() => {
validateToken()
}, []);
const updateUserContext = (newValues: Partial<IAuthContext>) => {
if (newValues.user !== undefined) {
setUser(newValues.user);
}
};
const contextValue: IAuthContext = {
user,
loading,
updateUserContext
};
return (
<AuthContext.Provider value={contextValue}>
{children}
</AuthContext.Provider>
);
}