feat: add web
ci-web / test (push) Failing after 26m34s

This commit is contained in:
Nuxgrid
2026-07-27 19:13:56 +02:00
parent bb6c425840
commit 07db8a2ae2
39 changed files with 7534 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
import { Navigate, Route, Routes } from 'react-router-dom'
import { Center, Spinner } from '@chakra-ui/react'
import { Landing } from './pages/Landing'
import { Pricing } from './pages/Pricing'
import { RequestDemo } from './pages/RequestDemo'
import { Login } from './pages/Login'
import { Register } from './pages/Register'
import { Leads } from './pages/backoffice/Leads'
import { Demos } from './pages/backoffice/Demos'
import { Messages } from './pages/backoffice/Contact'
import { Codes } from './pages/backoffice/Codes'
import { Subscription } from './pages/backoffice/Subscription'
import { PublicLayout } from './components/PublicLayout'
import { BackofficeLayout } from './components/BackofficeLayout'
import { Contact } from './pages/Contact'
import { useAuth } from './lib/auth'
import type { JSX } from 'react'
function RequireAuth({ children }: { children: JSX.Element }) {
const { isAuthenticated, initializing } = useAuth()
if (initializing) {
return (
<Center h="100vh">
<Spinner />
</Center>
)
}
return isAuthenticated ? children : <Navigate to="/login" replace />
}
// Réservé à l'admin : provisioning des démos.
function RequireAdmin({ children }: { children: JSX.Element }) {
const { isAdmin } = useAuth()
return isAdmin ? children : <Navigate to="/app/leads" replace />
}
// Accès aux leads : autorisé pour l'admin, ou pour les comptes non premium.
function RequireLeadsAccess({ children }: { children: JSX.Element }) {
const { isAdmin, isPremium } = useAuth()
const canAccess = isAdmin || !isPremium
return canAccess ? children : <Navigate to="/app/subscription" replace />
}
// Redirection d'accueil du back-office selon le rôle.
function BackofficeHome() {
const { role } = useAuth()
switch (role) {
case 'admin':
return <Navigate to="/app/demos" replace />
case 'client':
return <Navigate to="/app/subscription" replace />
default:
return <Navigate to="/app/leads" replace />
}
}
export function App() {
return (
<Routes>
{/* Vitrine publique (header + footer, sans authentification) */}
<Route element={<PublicLayout />}>
<Route path="/" element={<Landing />} />
<Route path="/tarifs" element={<Pricing />} />
<Route path="/demo" element={<RequestDemo />} />
<Route path="/contact" element={<Contact />} />
</Route>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
{/* Back-office protégé */}
<Route
path="/app"
element={
<RequireAuth>
<BackofficeLayout />
</RequireAuth>
}
>
<Route index element={<BackofficeHome />} />
<Route
path="leads"
element={
<RequireLeadsAccess>
<Leads />
</RequireLeadsAccess>
}
/>
<Route
path="demos"
element={
<RequireAdmin>
<Demos />
</RequireAdmin>
}
/>
<Route
path="codes"
element={
<RequireAdmin>
<Codes />
</RequireAdmin>
}
/>
<Route
path="messages"
element={
<RequireAdmin>
<Messages />
</RequireAdmin>
}
/>
<Route path="subscription" element={<Subscription />} />
</Route>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
)
}