Corp/frontend/src/contexts/UserContext.tsx
igor_nadein 814c12ceeb feat: integrate Next.js frontend with Django backend
- Add complete Next.js 16 frontend with TypeScript and Tailwind CSS
- Implement API proxy route for CORS-free backend communication
- Create UserContext for global authentication state management
- Add authentication flow with JWT tokens
- Implement real data integration for posts and employees pages
- Add dynamic user avatars (with fallback to initials)
- Update API types to match backend Employee serializer
- Remove all hardcoded mock data
- Add route protection with automatic redirect to /login
- Configure Docker orchestration for full-stack setup
2026-02-19 15:57:42 +03:00

87 lines
2.4 KiB
TypeScript

"use client";
import { createContext, useContext, useEffect, useState, ReactNode } from "react";
import { apiClient } from "@/lib/api";
import type { User } from "@/types/api";
interface UserContextType {
user: User | null;
loading: boolean;
error: string | null;
refreshUser: () => Promise<void>;
logout: () => void;
}
const UserContext = createContext<UserContextType | undefined>(undefined);
export function UserProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const loadUser = async () => {
try {
setLoading(true);
setError(null);
// Проверяем наличие токена
const token = typeof window !== 'undefined' ? localStorage.getItem('access_token') : null;
if (!token) {
setUser(null);
setLoading(false);
return;
}
// Загружаем данные пользователя
const userData = await apiClient.getCurrentUser();
setUser(userData);
} catch (err: any) {
console.error('Ошибка загрузки пользователя:', err);
setError(err.message);
setUser(null);
// Если ошибка 401 - токен невалиден, очищаем
if (err.message?.includes('401')) {
apiClient.clearToken();
}
} finally {
setLoading(false);
}
};
const refreshUser = async () => {
await loadUser();
};
const logout = () => {
apiClient.clearToken();
setUser(null);
if (typeof window !== 'undefined') {
window.location.href = '/login';
}
};
// Загружаем пользователя при монтировании
useEffect(() => {
loadUser();
}, []);
const value: UserContextType = {
user,
loading,
error,
refreshUser,
logout,
};
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}
export function useUser() {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
}