feat(auth): minimal login/logout + ProtectedRoute (B-LOGOUT)
- api/client.js: apiFetch подставляет Bearer-токен, выставляет Content-Type: application/json для не-FormData тел, ловит 401 -> событие - context/AuthContext: валидация токена через /auth/me, loading-гейт, logout(), подписка на 401 - components/ProtectedRoute: guard с ролями и заглушкой на время проверки - pages/Login: форма входа (OAuth2 form-urlencoded), редирект на from - App.js: AuthProvider, /login, ProtectedRoute на /sar /desktop /analysis /admin (admin -> roles=[admin]) /mobile - AdminDashboard/CaseForm/AnalysisResult: переход на apiFetch - AdminDashboard: кнопка "Выйти" в шапке (useAuth().logout) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import SearchMap from '../../components/SearchMap';
|
||||
import { apiFetch } from "../../api/client";
|
||||
import "./AnalysisResult.css";
|
||||
|
||||
const AnalysisResult = () => {
|
||||
@@ -16,7 +17,7 @@ const AnalysisResult = () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const caseResponse = await fetch(`/api/v1/cases/${caseId}`);
|
||||
const caseResponse = await apiFetch(`/api/v1/cases/${caseId}`);
|
||||
if (!caseResponse.ok) {
|
||||
throw new Error("Не удалось загрузить карточку");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user