Files
Mouigni 12fc18ea9d
Build & Deploy / build (push) Successful in 28s
Mise à jour interface et styles frontend
2026-08-16 17:25:45 +02:00

196 lines
6.0 KiB
TypeScript

import { useEffect, useState } from "react";
import { Routes, Route, Navigate, useLocation, useNavigate } from "react-router-dom";
import AuthPage from "./pages/AuthPage";
import HomePage from "./pages/Home";
import DocumentsPage from "./pages/Documents";
import IngredientSearchPage from "./pages/IngredientSearchPage";
import RecentUpdatesPage from "./pages/RecentUpdatesPage";
import AboutPage from "./pages/AboutPage";
import ContactPage from "./pages/ContactPage";
import CGU from "./pages/CGU";
import MentionsLegales from "./pages/MentionsLegales";
import Admin from "./pages/Admin";
import AdminRoute from "./components/AdminRoute";
import Sidebar from "./components/Sidebar";
import Footer from "./components/Footer";
import CookieBanner from "./components/CookieBanner";
import Toasts from "./components/Toast";
import BackToTop from "./components/BackToTop";
import styles from "./App.module.css";
import { getDocuments, API_URL, type ApiDocument } from "./services/theapi";
type NavItem =
| "home"
| "ingredient-search"
| "documents"
| "recent-updates"
| "about"
| "contact"
| "cgu"
| "mentions-legales"
| "admin";
interface User {
id: number;
email: string;
full_name: string | null;
}
interface AuthState {
user: User | null;
isAuthenticated: boolean;
loading: boolean;
}
export default function App() {
const [recentDocuments, setRecentDocuments] = useState<ApiDocument[]>([]);
const [authState, setAuthState] = useState<AuthState>(() => {
const savedToken = localStorage.getItem("authToken");
const savedUser = localStorage.getItem("user");
if (savedToken && savedUser) {
const parsedUser = JSON.parse(savedUser);
return {
user: parsedUser,
isAuthenticated: true,
loading: false,
};
}
return {
user: null,
isAuthenticated: false,
loading: false,
};
});
const location = useLocation();
const navigate = useNavigate();
const handleAuthSuccess = (newToken: string, newUser: User) => {
localStorage.setItem("authToken", newToken);
localStorage.setItem("user", JSON.stringify(newUser));
setAuthState({
user: newUser,
isAuthenticated: true,
loading: false,
});
navigate("/");
};
const handleLogout = () => {
localStorage.removeItem("authToken");
localStorage.removeItem("user");
setAuthState({
user: null,
isAuthenticated: false,
loading: false,
});
navigate("/");
};
const activeNav: NavItem =
location.pathname === "/ingredient-search" ? "ingredient-search"
: location.pathname === "/documents" ? "documents"
: location.pathname === "/recent-updates" ? "recent-updates"
: location.pathname === "/about" ? "about"
: location.pathname === "/contact" ? "contact"
: location.pathname === "/cgu" ? "cgu"
: location.pathname === "/mentions-legales"? "mentions-legales"
: location.pathname === "/admin"? "admin"
: "home";
useEffect(() => {
const token = localStorage.getItem("authToken");
if (!token) return;
fetch(`${API_URL}/me?token=${encodeURIComponent(token)}`)
.then((res) => (res.ok ? res.json() : Promise.reject(res.status)))
.then((freshUser: User) => {
localStorage.setItem("user", JSON.stringify(freshUser));
setAuthState((prev) => ({ ...prev, user: freshUser }));
})
.catch((err) => console.error("Rafraîchissement du profil impossible :", err));
}, []);
useEffect(() => {
if (authState.isAuthenticated) {
getDocuments()
.then((data) => {
setRecentDocuments(Array.isArray(data) ? data.slice(0, 4) : []);
})
.catch((err) => {
console.error("API ERROR:", err);
setRecentDocuments([]);
});
}
}, [authState.isAuthenticated]);
const handleNavClick = (item: NavItem) => {
const path =
item === "home" ? "/"
: item === "documents" ? "/documents"
: item === "ingredient-search" ? "/ingredient-search"
: item === "recent-updates" ? "/recent-updates"
: item === "about" ? "/about"
: item === "contact" ? "/contact"
: item === "cgu" ? "/cgu"
: item === 'admin' ? '/admin'
: "/mentions-legales";
navigate(path);
};
if (authState.loading) {
return (
<div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "#f8fafc" }}>
<p style={{ color: "#475569", fontSize: "1.125rem" }}>Loading application...</p>
</div>
);
}
if (!authState.isAuthenticated) {
return (
<>
<AuthPage onAuthSuccess={handleAuthSuccess} />
<CookieBanner />
</>
);
}
return (
<div className={styles.app}>
<Toasts />
<div className={styles.contentWrapper}>
<Sidebar
activeNav={activeNav}
onNavClick={handleNavClick}
onLogout={handleLogout}
user={authState.user}
/>
<main className={styles.main}>
<Routes>
<Route path="/" element={<HomePage handleNavClick={handleNavClick} recentDocuments={recentDocuments} />} />
<Route path="/documents" element={<DocumentsPage />} />
<Route path="/ingredient-search" element={<IngredientSearchPage />} />
<Route path="/recent-updates" element={<RecentUpdatesPage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/contact" element={<ContactPage />} />
<Route path="/cgu" element={<CGU />} />
<Route path="/mentions-legales" element={<MentionsLegales />} />
<Route path="/admin" element={<AdminRoute user={authState.user}><Admin /></AdminRoute>} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</main>
</div>
<Footer onNavClick={handleNavClick} />
<CookieBanner />
<BackToTop />
</div>
);
}