creat modul critial
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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 && (
|
||||
<div className="critical-alert-overlay">
|
||||
<div className="critical-alert-box">
|
||||
<h2>⚠️ Alerte Critique ⚠️</h2>
|
||||
<p>Contacter votre webmaster - défaut critique du système</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isActive && (
|
||||
<style>
|
||||
{`body { opacity: ${opacity}; transition: opacity 1s linear; }`}
|
||||
</style>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CriticalAlert;
|
||||
@@ -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 (
|
||||
<div>
|
||||
<h2>Panneau Administrateur</h2>
|
||||
<button
|
||||
onClick={activateAlert}
|
||||
style={{ backgroundColor: "red", color: "white", padding: "10px", marginRight: "10px" }}
|
||||
disabled={isActive}
|
||||
>
|
||||
Activer l'Alerte Critique
|
||||
</button>
|
||||
<button
|
||||
onClick={deactivateAlert}
|
||||
style={{ backgroundColor: "green", color: "white", padding: "10px" }}
|
||||
disabled={!isActive}
|
||||
>
|
||||
Désactiver l'Alerte Critique
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdminDashboard;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Helmet } from "react-helmet"; // Permet de gérer les balises <head>
|
||||
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 (
|
||||
<div className="backtime-container">
|
||||
<Helmet>
|
||||
<meta name="robots" content="noindex, nofollow" /> {/* 🚫 Interdit l'indexation par Google */}
|
||||
<title>Page introuvable</title>
|
||||
</Helmet>
|
||||
|
||||
{isAuthenticated ? (
|
||||
<>
|
||||
<h2>Gestion du module d'alerte critique</h2>
|
||||
<button onClick={handleLogout} className="logout-button">
|
||||
Déconnexion
|
||||
</button>
|
||||
<div className="switch-container">
|
||||
<SwitchControl />
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="login-container">
|
||||
<h2>Accès Restreint</h2>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Entrez le mot de passe"
|
||||
value={inputPassword}
|
||||
onChange={(e) => setInputPassword(e.target.value)}
|
||||
/>
|
||||
<button onClick={handleLogin} className="login-button">Valider</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<div className="switch-container">
|
||||
<label className="switch">
|
||||
<input type="checkbox" checked={isActive} onChange={toggleAlert} />
|
||||
<span className="slider"></span>
|
||||
</label>
|
||||
<span className={`status-indicator ${isActive ? "active" : "inactive"}`}>
|
||||
{isActive ? "Module Actif" : "Module Inactif"}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Backtime;
|
||||
@@ -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() {
|
||||
<Suspense fallback={<div>Chargement...</div>}>
|
||||
<Router>
|
||||
<Header />
|
||||
<CriticalAlert />
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/posts" element={<Post />} />
|
||||
@@ -37,6 +41,8 @@ function YourApp() {
|
||||
<Route path="/services/prestation-maitrise-oeuvre" element={<ServiceUn />} />
|
||||
<Route path="/services/formation-ia" element={<ServiceDeux />} />
|
||||
<Route path="/services/formation-video" element={<ServiceTrois />} />
|
||||
<Route path="/backtime" element={<Backtime />} />
|
||||
<Route path="/admin" element={<AdminDashboard />} />
|
||||
</Routes>
|
||||
<Footer />
|
||||
</Router>
|
||||
@@ -44,6 +50,7 @@ function YourApp() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
|
||||
Reference in New Issue
Block a user