T07a: frontend core SPA — shell + auth + routing + i18n + UI library + a11y
- React 18 + Vite + TypeScript + Tailwind CSS setup - AppShell with Sidebar (plugin menu) + TopBar (tenant switcher, search, notifications, user menu) - Auth pages: Login, PasswordResetRequest, PasswordResetConfirm - Protected routes with auth guard - API client (axios with interceptors: session cookie, 401 redirect, 422 validation) - TanStack Query hooks for auth, users, companies, contacts, notifications - Zustand stores: authStore, uiStore - i18n setup (de/en locales) with react-i18next - UI component library: Button, Input, Select, Modal, Toast, Table, Card, Badge, Avatar, Pagination, EmptyState, Skeleton, ConfirmDialog - Accessibility: ARIA labels, 44px touch targets, keyboard nav, reduced-motion, sr-only - Design tokens from prototype as CSS custom properties - 111 tests passing across 20 test files - tsc --noEmit: 0 errors - npm run build: success (471KB JS, 24KB CSS)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { AppRouter } from '@/routes';
|
||||
import { setUnauthorizedHandler } from '@/api/client';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: 1,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default function App() {
|
||||
const { logout } = useAuthStore();
|
||||
|
||||
React.useEffect(() => {
|
||||
setUnauthorizedHandler(() => {
|
||||
logout();
|
||||
window.location.href = '/login';
|
||||
});
|
||||
}, [logout]);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppRouter />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user