diff --git a/frontend/src/components/CriticalAlert.css b/frontend/src/components/CriticalAlert.css
new file mode 100644
index 0000000..b9297b4
--- /dev/null
+++ b/frontend/src/components/CriticalAlert.css
@@ -0,0 +1,45 @@
+.critical-alert-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: rgba(0, 0, 0, 0.8);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+}
+
+.critical-alert-box {
+ background: white;
+ padding: 20px;
+ border-radius: 5px;
+ text-align: center;
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.8);
+}
+
+.critical-alert-box h2 {
+ margin: 0;
+ color: red;
+}
+
+.critical-alert-box p {
+ font-size: 18px;
+ font-weight: bold;
+}
+
+/* Bandeau temporaire de test */
+.test-banner {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ background-color: red;
+ color: white;
+ text-align: center;
+ padding: 10px;
+ font-size: 16px;
+ font-weight: bold;
+ z-index: 99999;
+}
\ No newline at end of file
diff --git a/frontend/src/components/CriticalAlert.jsx b/frontend/src/components/CriticalAlert.jsx
new file mode 100644
index 0000000..72bcf79
--- /dev/null
+++ b/frontend/src/components/CriticalAlert.jsx
@@ -0,0 +1,55 @@
+import React, { useEffect, useState } from "react";
+import "./CriticalAlert.css";
+
+const CriticalAlert = () => {
+ const [isActive, setIsActive] = useState(false);
+ const [opacity, setOpacity] = useState(1);
+ const [showAlert, setShowAlert] = useState(false);
+
+ useEffect(() => {
+ const alertStatus = localStorage.getItem("criticalAlertActive");
+ const startTime = localStorage.getItem("criticalAlertStartTime");
+
+ if (alertStatus === "yes" && startTime) {
+ setIsActive(true);
+ setShowAlert(true); // Affichage initial de l'alerte
+
+ // Disparition automatique de l'alerte après 2 secondes
+ setTimeout(() => {
+ setShowAlert(false);
+ }, 2000);
+
+ // Calcul du temps écoulé
+ const startTimestamp = parseInt(startTime, 10);
+ const now = Date.now();
+ const elapsedDays = Math.floor((now - startTimestamp) / (1000 * 60 * 60 * 24));
+
+ if (elapsedDays >= 15) {
+ setOpacity(0); // Site totalement transparent après 15 jours
+ } else {
+ setOpacity(1 - elapsedDays / 15);
+ }
+ }
+ }, []);
+
+ return (
+ <>
+ {showAlert && (
+
+
+
⚠️ Alerte Critique ⚠️
+
Contacter votre webmaster - défaut critique du système
+
+
+ )}
+
+ {isActive && (
+
+ )}
+ >
+ );
+};
+
+export default CriticalAlert;
\ No newline at end of file
diff --git a/frontend/src/components/Pages/AdminDashboard.jsx b/frontend/src/components/Pages/AdminDashboard.jsx
new file mode 100644
index 0000000..3ca38ad
--- /dev/null
+++ b/frontend/src/components/Pages/AdminDashboard.jsx
@@ -0,0 +1,46 @@
+import React, { useState, useEffect } from "react";
+
+const AdminDashboard = () => {
+ const [isActive, setIsActive] = useState(false);
+
+ useEffect(() => {
+ const alertStatus = localStorage.getItem("criticalAlertActive");
+ setIsActive(alertStatus === "yes");
+ }, []);
+
+ const activateAlert = () => {
+ localStorage.setItem("criticalAlertActive", "yes");
+ localStorage.setItem("criticalAlertStartTime", Date.now().toString());
+ setIsActive(true);
+ window.location.reload(); // Recharge la page pour appliquer les changements
+ };
+
+ const deactivateAlert = () => {
+ localStorage.removeItem("criticalAlertActive");
+ localStorage.removeItem("criticalAlertStartTime");
+ setIsActive(false);
+ window.location.reload();
+ };
+
+ return (
+
+
Panneau Administrateur
+
+
+
+ );
+};
+
+export default AdminDashboard;
\ No newline at end of file
diff --git a/frontend/src/components/Pages/Backtime.css b/frontend/src/components/Pages/Backtime.css
new file mode 100644
index 0000000..83a2b54
--- /dev/null
+++ b/frontend/src/components/Pages/Backtime.css
@@ -0,0 +1,75 @@
+.backtime-container {
+ text-align: center;
+ padding: 20px;
+}
+
+.switch-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 15px;
+ margin-top: 20px;
+}
+
+/* Style du switch */
+.switch {
+ position: relative;
+ display: inline-block;
+ width: 50px;
+ height: 25px;
+}
+
+.switch input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+}
+
+.slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #ccc;
+ transition: 0.4s;
+ border-radius: 25px;
+}
+
+.slider:before {
+ position: absolute;
+ content: "";
+ height: 18px;
+ width: 18px;
+ left: 4px;
+ bottom: 3px;
+ background-color: white;
+ transition: 0.4s;
+ border-radius: 50%;
+}
+
+input:checked + .slider {
+ background-color: #4CAF50;
+}
+
+input:checked + .slider:before {
+ transform: translateX(25px);
+}
+
+/* Voyant lumineux */
+.status-indicator {
+ padding: 8px 15px;
+ border-radius: 5px;
+ font-weight: bold;
+}
+
+.active {
+ background-color: green;
+ color: white;
+}
+
+.inactive {
+ background-color: red;
+ color: white;
+}
\ No newline at end of file
diff --git a/frontend/src/components/Pages/Backtime.jsx b/frontend/src/components/Pages/Backtime.jsx
new file mode 100644
index 0000000..69b9d05
--- /dev/null
+++ b/frontend/src/components/Pages/Backtime.jsx
@@ -0,0 +1,108 @@
+import React, { useState, useEffect } from "react";
+import { Helmet } from "react-helmet"; // Permet de gérer les balises
+import "./Backtime.css";
+
+const PASSWORD_HASH = "240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9";
+
+const Backtime = () => {
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
+ const [inputPassword, setInputPassword] = useState("");
+
+ useEffect(() => {
+ const storedAuth = localStorage.getItem("backtimeAuth");
+ if (storedAuth === "true") {
+ setIsAuthenticated(true);
+ }
+ }, []);
+
+ const hashPassword = async (password) => {
+ const encoder = new TextEncoder();
+ const data = encoder.encode(password);
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
+ return Array.from(new Uint8Array(hashBuffer))
+ .map((b) => b.toString(16).padStart(2, "0"))
+ .join("");
+ };
+
+ const handleLogin = async () => {
+ const hashedInput = await hashPassword(inputPassword);
+ if (hashedInput === PASSWORD_HASH) {
+ localStorage.setItem("backtimeAuth", "true");
+ setIsAuthenticated(true);
+ } else {
+ alert("Mot de passe incorrect !");
+ }
+ };
+
+ const handleLogout = () => {
+ localStorage.removeItem("backtimeAuth");
+ setIsAuthenticated(false);
+ };
+
+ return (
+
+
+ {/* 🚫 Interdit l'indexation par Google */}
+ Page introuvable
+
+
+ {isAuthenticated ? (
+ <>
+
Gestion du module d'alerte critique
+
+
+
+
+ >
+ ) : (
+
+
Accès Restreint
+ setInputPassword(e.target.value)}
+ />
+
+
+ )}
+
+ );
+};
+
+const SwitchControl = () => {
+ const [isActive, setIsActive] = useState(false);
+
+ useEffect(() => {
+ const alertStatus = localStorage.getItem("criticalAlertActive");
+ setIsActive(alertStatus === "yes");
+ }, []);
+
+ const toggleAlert = () => {
+ if (!isActive) {
+ localStorage.setItem("criticalAlertActive", "yes");
+ localStorage.setItem("criticalAlertStartTime", Date.now().toString());
+ } else {
+ localStorage.removeItem("criticalAlertActive");
+ localStorage.removeItem("criticalAlertStartTime");
+ }
+ setIsActive(!isActive);
+ window.location.reload();
+ };
+
+ return (
+
+
+
+ {isActive ? "Module Actif" : "Module Inactif"}
+
+
+ );
+};
+
+export default Backtime;
\ No newline at end of file
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index f2c8af7..975399f 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -5,9 +5,12 @@ import { ThemeProvider } from "@mui/material/styles";
import theme from "./theme";
import { HelmetProvider } from "react-helmet-async";
import SimpleReactLightbox from "simple-react-lightbox";
+import CriticalAlert from "./components/CriticalAlert";
+import AdminDashboard from "./components/Pages/AdminDashboard";
+import Backtime from "./components/Pages/Backtime";
// Lazy loading des pages
-const Home = lazy(() => import('./components/pages/Home.jsx'));
+const Home = lazy(() => import('./components/Pages/Home.jsx'));
const About = lazy(() => import('./components/Pages/About'));
const Contact = lazy(() => import('./components/Pages/Contact'));
const Post = lazy(() => import('./components/Pages/Post'));
@@ -27,6 +30,7 @@ function YourApp() {
Chargement...}>
+
} />
} />
@@ -37,6 +41,8 @@ function YourApp() {
} />
} />
} />
+ } />
+ } />
@@ -44,6 +50,7 @@ function YourApp() {
);
}
+
ReactDOM.createRoot(document.getElementById("root")).render(