This commit is contained in:
Mikan
2025-06-02 17:30:35 +03:00
parent b5b2439bd8
commit 7538faa699
18 changed files with 528 additions and 212 deletions

View File

@@ -1,13 +1,15 @@
import {UserContext} from "./UserContext.ts";
import {useContext} from "react";
import {UserContextType} from "../../types/users.ts";
export function useUser() {
export function useUser(): undefined| UserContextType {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within a UserProvider');
console.error('useUser must be used within a UserProvider');
return undefined;
}
return context;
}
}

View File

@@ -1,10 +1,5 @@
import {Account} from "../../types/users.ts";
import {UserContextType} from "../../types/users.ts";
import {createContext} from "react";
export type UserContextType = {
user: Account | undefined;
login: (userData: Account) => void;
logout: () => void;
};
export const UserContext = createContext<UserContextType | undefined>(undefined);

View File

@@ -1,6 +1,9 @@
import React, {ReactNode, useEffect, useState} from 'react';
import {Account} from '../../types/users.ts';
import {Account, JwtTokenResponse, TokenObtainPair} from '../../types/users.ts';
import {UserContext} from "./UserContext.ts";
import {refreshToken, verifyToken, login as apiLogin} from "../../API/users.ts";
import {getFetch} from "../../API/common.ts";
import {deleteCookie, getCookie, setCookie} from "../cookies.ts";
export function UserProvider({ children }: { children: ReactNode }) {
@@ -8,27 +11,87 @@ export function UserProvider({ children }: { children: ReactNode }) {
const storedUser = localStorage.getItem('user');
return storedUser ? JSON.parse(storedUser) : undefined;
});
const [tokens, setTokens] = useState<JwtTokenResponse | undefined>(() => {
const accessToken = getCookie('access_token');
const refreshToken = getCookie('refresh_token');
return accessToken && refreshToken ? { access: accessToken, refresh: refreshToken } : undefined;
});
useEffect(() => {
if (tokens?.access) {
// Устанавливаем куки для токенов
setCookie('access_token', tokens.access, 7);
setCookie('refresh_token', tokens.refresh, 7);
fetchCurrentUser().then(userData => setUser(userData));
} else {
// Удаляем куки, если токены отсутствуют
deleteCookie('access_token');
deleteCookie('refresh_token');
}
}, [tokens]);
useEffect(() => {
console.log(user)
if (user) {
localStorage.setItem('user', JSON.stringify(user));
document.cookie = `user=${encodeURIComponent(JSON.stringify(user))}; path=/;`;
} else {
localStorage.removeItem('user');
document.cookie = 'user=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;';
}
}, [user]);
const login = (userData: Account) => {
setUser(userData);
const fetchCurrentUser = async (): Promise<Account | undefined> => {
let response = await getFetch(`/users/auth/users/me/`);
if (!response.success){
return undefined;
}
response = await getFetch(`/users/auth/users/${(response.body as Account).id}/`);
if (response.success){
return response.body as Account
}
// if (response?.success && response.body) {
// return response.body as Account; // Возвращаем данные о пользователе
// }
return undefined;
};
const logout = () => {
setUser(undefined);
const handleLogin = async (credentials: TokenObtainPair) => {
const tokens = await apiLogin(credentials);
if (tokens) {
setTokens(tokens);
}
};
const handleLogout = () => {
setUser(undefined);
setTokens(undefined);
};
const validateToken = async () => {
if (tokens?.access) {
const isValid = await verifyToken({ token: tokens.access });
if (!isValid && tokens.refresh) {
const newTokens = await refreshToken({ refresh: tokens.refresh });
if (newTokens) {
setTokens(newTokens);
} else {
handleLogout();
}
} else if (!isValid) {
handleLogout();
}
}
};
useEffect(() => {
validateToken().then();
}, []);
return (
<UserContext.Provider value={{ user, login, logout }}>
<UserContext.Provider value={{ user, login: handleLogin, logout: handleLogout }}>
{children}
</UserContext.Provider>
);