arm-core/web/src/auth/AuthGate.tsx
Andrey Epifancev 498450b763 feat(web): API-клиент с Bearer, dev-вход по email, загрузка /me
Токен хранится в sessionStorage (design D-9; без Redux): живёт до закрытия вкладки, все обращения к хранилищу в try/catch с запасным токеном в памяти.
apiFetch подставляет Bearer, на 401 сбрасывает токен и шлёт событие armka:unauthorized, ошибки разбирает по трём формам detail (строка / {code,message} / массив 422).
useMe не ходит в /me без токена и отбрасывает устаревшие ответы (флаг cancelled), AuthGate показывает вход, пока профиля нет.
Форма DevLogin вырезается из production-сборки по литералу process.env.NODE_ENV; через Config это не работает: process.env там заменён объектом REACT_APP_*.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 00:23:56 +04:00

19 lines
691 B
TypeScript

import { Spin } from 'antd';
import type { ReactNode } from 'react';
import { DevLogin } from './DevLogin';
import { MeContext } from './MeContext';
import { useMe } from './useMe';
// Пока профиль не загружен — вход (или индикатор загрузки); после входа дети получают профиль через `useCurrentUser`.
export function AuthGate({ children }: { children: ReactNode }) {
const { me, loading, error, reload } = useMe();
if (loading) {
return <Spin fullscreen />;
}
if (!me) {
return <DevLogin onLogin={reload} error={error} />;
}
return <MeContext.Provider value={me}>{children}</MeContext.Provider>;
}