diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/client/src/App.tsx b/client/src/App.tsx index 5c7a610..1f85b3c 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,39 +1,132 @@ import { Toaster } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import NotFound from "@/pages/NotFound"; -import { Route, Switch } from "wouter"; +import { Route, Switch, Redirect } from "wouter"; import ErrorBoundary from "./components/ErrorBoundary"; import { ThemeProvider } from "./contexts/ThemeContext"; -import Home from "./pages/Home"; +import { LocalAuthProvider, useLocalAuth } from "./contexts/LocalAuthContext"; +import { AppLayout } from "./components/AppLayout"; +import Login from "./pages/Login"; +import VeilleDashboard from "./pages/VeilleDashboard"; +import AAPDashboard from "./pages/AAPDashboard"; +import Settings from "./pages/Settings"; +import UsersAdmin from "./pages/UsersAdmin"; +import ImportLogs from "./pages/ImportLogs"; +import { Loader2 } from "lucide-react"; + +// ─── Guard d'authentification ───────────────────────────────────────────────── + +function AuthGuard({ children }: { children: React.ReactNode }) { + const { user, loading } = useLocalAuth(); + + if (loading) { + return ( +
Veille Réglementaire
+Direction des Opérations
+{user?.name || "Utilisateur"}
+{user?.role === "admin" ? "Administrateur" : user?.role === "readonly" ? "Lecture seule" : "Utilisateur"}
++ Handicap, Personnes Âgées, Enfance, Précarité, Sanitaire et Autre +
+Aucun appel à projets trouvé
+Modifiez vos filtres ou importez des données
+| # | +Titre | +Catégorie | +Région | +Département | +Publication | +Clôture | +Lien | +
|---|---|---|---|---|---|---|---|
| {idx + 1} | +
+ {item.titre} + |
+
+ |
+ {item.region || "—"} | +{item.departement || "—"} | +{formatDate(item.datePublication) || "—"} | +
+ {item.lien && (
+
+ |
+
Historique des imports automatiques et manuels
+{stat.value}
+Aucun log d'import
+Les imports apparaîtront ici
+| Date | +Fichier | +Statut | +Nouvelles | +Ignorées | +Total | +Durée | +Message | +
|---|---|---|---|---|---|---|---|
|
+
+
+ |
+
+ |
+
+ |
+ + +{log.newRows} + | +{log.skippedRows} | +{log.totalRows} | ++ {log.startedAt && log.completedAt + ? `${((new Date(log.completedAt).getTime() - new Date(log.startedAt).getTime()) / 1000).toFixed(1)}s` + : "—"} + | ++ {log.errorMessage ? ( + {log.errorMessage} + ) : "—"} + | +
Direction des Opérations — Itinova
+
+ Compte par défaut : admin@itinova.fr
+
+ Mot de passe : Admin@Itinova2024!
+
+ © {new Date().getFullYear()} Itinova — Application interne +
+Configuration de l'application et des imports
+
+ Obtenez un token via Azure Active Directory avec les permissions Files.Read. Les URLs des fichiers doivent être des liens de téléchargement directs.
+
+ Prochain import : demain à {form.import_time || "06:00"} +
+{users.length} utilisateur{users.length !== 1 ? "s" : ""} enregistré{users.length !== 1 ? "s" : ""}
+Aucun utilisateur
+| Nom | +Rôle | +Statut | +Dernière connexion | +Actions | +|
|---|---|---|---|---|---|
|
+
+
+
+ {user.name[0]?.toUpperCase()}
+
+ {user.name}
+ |
+ {user.email} | +
+ |
+
+ {user.isActive ? (
+
+ |
+ + {user.lastSignedIn + ? format(new Date(user.lastSignedIn), "d MMM yyyy", { locale: fr }) + : "Jamais"} + | +
+
+
+
+
+ |
+
+ Suivi réglementaire, concurrentiel, technologique et général +
+Aucun résultat trouvé
+Modifiez vos filtres ou importez des données
+| # | +Titre | +Type | +Catégorie | +Niveau | +Territoire | +Date | +Lien | +
|---|---|---|---|---|---|---|---|
| {idx + 1} | +
+
+
+ {item.titre} + {item.resume &&{item.resume} } + |
+
+ |
+ {item.categorie || "—"} | +{item.niveau || "—"} | +{item.territoire || "—"} | +{formatDate(item.datePublication) || "—"} | +
+ {item.lien && (
+
+ |
+
{item.resume}
} +