feat(web): Login/Register страницы, protected routes, logout
- ProtectedRoute: loading -> спиннер, !user -> /login, иначе children - LoginPage/RegisterPage: field+react-hook-form/zod, ошибка через role=alert, редирект на /domains при успехе/уже авторизован - main.tsx: AuthProvider + QueryCache/MutationCache onError -> notifyUnauthorized на UnauthorizedError (сброс сессии из кода вне React-дерева) - AuthContext: logout и notifyUnauthorized чистят react-query кэш (qc.clear()) - Layout: email пользователя + кнопка Выйти - App: /login и /register публичные (авторизованный -> /domains), остальное под ProtectedRoute Починка page-тестов (Accounts/Domains/Templates/DomainDiff/App): AuthProvider + мок api.auth.me, спай-ассерты обновлены под projectId-первым-аргументом сигнатур api.* (T5).
This commit is contained in:
+22
-5
@@ -4,18 +4,35 @@ import "@fontsource/ibm-plex-mono/500.css"
|
||||
import "./index.css"
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import { QueryCache, QueryClient, QueryClientProvider, MutationCache } from "@tanstack/react-query"
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
import { UnauthorizedError } from "@/api/client"
|
||||
import { AuthProvider, notifyUnauthorized } from "@/auth/AuthContext"
|
||||
import { App } from "./App"
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
// A 401 from *any* query or mutation means the session died server-side
|
||||
// (expired/destroyed cookie) — drop it from here rather than requiring every
|
||||
// hook in useApi.ts to remember to handle it individually. AuthContext reacts
|
||||
// via notifyUnauthorized (registered by AuthProvider), which resets
|
||||
// user/project and clears the cache; ProtectedRoute then redirects to
|
||||
// /login on the next render.
|
||||
function onQueryError(error: unknown) {
|
||||
if (error instanceof UnauthorizedError) notifyUnauthorized()
|
||||
}
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
queryCache: new QueryCache({ onError: onQueryError }),
|
||||
mutationCache: new MutationCache({ onError: onQueryError }),
|
||||
})
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
<AuthProvider>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</React.StrictMode>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user