DashboardLayout

This commit is contained in:
Mikan
2025-06-02 18:11:15 +03:00
parent ab10918dc4
commit 054cb63d71
5 changed files with 70 additions and 43 deletions

View File

@@ -29,7 +29,7 @@ export function useDataPage<T>(application:string, endpoint: string, params:{[ke
})
}
},
[data, application, endpoint, needLoad]
[data, application, endpoint, needLoad, params]
)
// function changePage(pageUrl: string|undefined) {
@@ -92,7 +92,7 @@ export function useData<T>(application:string, endpoint: string, id: string|numb
}
interface CachedData<T>{
get(id: string | number, needLoad: boolean): T|undefined|null
get(id: string | number, needLoad?: boolean): T|undefined|null
}
export function useCachedData<T>(application: string, endpoint: string): CachedData<T> {

View File

@@ -1,29 +1,46 @@
import {useUser} from "../utils/users/UseUser.ts";
import {Outlet, useNavigate} from "react-router-dom";
import React, {useEffect} from "react";
import { useUser } from "../utils/users/UseUser.ts"; // Хук для получения информации о пользователе
import { Outlet, Link, useNavigate } from "react-router-dom"; // Композиция для маршрутизации
import React, { useEffect } from "react";
import {UserContextType} from "../types/users.ts";
export function DashboardLayout() {
const { user } = useUser();
const navigate = useNavigate();
const { user, logout } = useUser() as UserContextType; // Получаем данные о пользователе
const navigate = useNavigate(); // Получаем функцию для навигации
// Проверяем, есть ли пользователь, если нет, редиректим на страницу логина
useEffect(() => {
if (!user) {
navigate("/login/")
navigate("/login/");
}
}, [navigate, user]);
if (!user){
return null;
if (!user) {
return null; // Если пользователь не найден, ничего не отображаем
}
// Определяем класс для активной ссылки
const isActive = (path: string) => window.location.pathname.includes(path)? 'selected' : 'unselected';
return (
<>
<div className="header">
<div className="dashboard-layout">
<div className="sidebar">
<h1 className="logo">Pro-Fi</h1>
<p className="role">{user.roleTitle || "Роль не опознана"}</p> {/* Отображаем текущую роль пользователя */}
<nav className="navigation">
<Link to="/dashboard/staff" className={isActive('/dashboard/staff')}>Штат</Link>
<Link to="/dashboard/schools" className={isActive('/dashboard/schools')}>Школы</Link>
<Link to="/dashboard/events" className={isActive('/dashboard/events')}>Мероприятия</Link>
<Link to="/dashboard/students" className={isActive('/dashboard/students')}>Студенты</Link>
<Link to="/dashboard/reports" className={isActive('/dashboard/reports')}>Отчеты</Link>
<Link to="/dashboard/partners" className={isActive('/dashboard/partners')}>Партнеры</Link>
<Link to="/admin" className={isActive('/admin')}>Админ-панель</Link>
<button onClick={logout} className="logout">Выйти</button>
</nav>
</div>
<div className="content">
<Outlet />
</div>
</>
</div>
);
}

View File

@@ -23,12 +23,18 @@ export function LoginPage() {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (login && loginInput && password) {
let success = false;
try {
await login({ login: loginInput, password });
success = await login({ login: loginInput, password });
setError(null);
if (!success){
setError('Ошибка входа');
}
} catch {
setError('Ошибка входа');
}
}
};

View File

@@ -2,7 +2,7 @@ import {UniqueItem} from "./common.ts";
export type UserContextType = {
user: Account | undefined;
login: (credentials: TokenObtainPair) => Promise<void>;
login: (credentials: TokenObtainPair) => Promise<boolean>;
logout: () => void;
};
@@ -14,13 +14,11 @@ export interface ContactData{
email?:string;
}
interface Role extends UniqueItem{
title: string;
}
export interface Account extends UniqueItem, ContactData{
login: string;
role?: Role;
role?: number;
roleTitle?: string;
is_staff: boolean;
is_active: boolean;

View File

@@ -31,7 +31,6 @@ export function UserProvider({ children }: { children: ReactNode }) {
}, [tokens]);
useEffect(() => {
console.log(user)
if (user) {
localStorage.setItem('user', JSON.stringify(user));
} else {
@@ -48,21 +47,27 @@ export function UserProvider({ children }: { children: ReactNode }) {
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; // Возвращаем данные о пользователе
// }
if (!response.success){
return undefined;
}
const account = response.body as Account ;
if (account.role){
response = await getFetch(`/users/roles/${account.role}/`);
if (response.success){
account.roleTitle = (response.body as {name:string}).name;
}
}
return account;
};
const handleLogin = async (credentials: TokenObtainPair) => {
const tokens = await apiLogin(credentials);
if (tokens) {
setTokens(tokens);
return true;
}
return false;
};
const handleLogout = () => {
@@ -70,7 +75,10 @@ export function UserProvider({ children }: { children: ReactNode }) {
setTokens(undefined);
};
const validateToken = async () => {
useEffect(() => {
async function validateToken() {
if (tokens?.access) {
const isValid = await verifyToken({ token: tokens.access });
if (!isValid && tokens.refresh) {
@@ -84,11 +92,9 @@ export function UserProvider({ children }: { children: ReactNode }) {
handleLogout();
}
}
};
useEffect(() => {
}
validateToken().then();
}, []);
}, [tokens]);
return (
<UserContext.Provider value={{ user, login: handleLogin, logout: handleLogout }}>