fix(frontend): address M1-M3 polish from code-reviewer

M1 — Single SessionProvider via nested router.
  The previous router had two route entries with `path: '/'`
  (Navigate, AppShell) plus a separate `/login` entry, each wrapped in
  its own RootLayout. That instantiated SessionProvider three times,
  forking state the moment session writes diverged across siblings.
  Replaced by one Root route with SessionProvider + <Outlet />, and
  index/login/AppShell-children nested underneath. RootLayout (the
  per-tree wrapper) is now obsolete and deleted; the new Root component
  lives in src/routing/Root.tsx (addresses NIT N4 as a side effect).

M2 — Typo: "pollign" → "polling" in LiveCockpitPage masthead.

M3 — Replace asymmetric `?? 'rt_operator'` / `?? 'soc_analyst'`
  fallbacks in LiveCockpitPage with an explicit `if (!user) return null;`
  guard placed after all hooks (rules-of-hooks). AppShell already
  redirects unauthenticated visitors to /login, so the guard documents
  the invariant rather than introducing one.

NITs N1-N3, N5-N7 recorded in tasks/todo.md as sprint 1+ follow-ups.
This commit is contained in:
ux-frontend
2026-05-21 20:44:32 +02:00
parent 12bc33469c
commit b505a654f8
5 changed files with 76 additions and 56 deletions

View File

@@ -0,0 +1,16 @@
import { Outlet } from 'react-router-dom';
import { SessionProvider } from '@/session/SessionContext';
/**
* Root route element. Mounts SessionProvider once for the entire app so
* every nested route — login, app shell, fallback — shares one session
* state. Kept in its own file so router.tsx exports only the router
* config (fast-refresh friendly).
*/
export function Root() {
return (
<SessionProvider>
<Outlet />
</SessionProvider>
);
}