- [ ERREUR ] : {error}
+ {/* MODULE 1 : BARE-METAL (HESTIACP) */}
+
- )}
- {/* ZONE DES SERVICES ACTIFS */}
- {!loading && !error && (
- <>
-
INFRASTRUCTURE ACTIVE
-
- {orders.length === 0 ? (
-
- Aucun service actif détecté.
-
+ {/* MODULE 2 : CLOUD (NEXTCLOUD) */}
+
+
ACTIF
+
// Sanctuaire Cloud
+
+ Stockage chiffré Nextcloud (cloud.gise.be). Synchronisation des terminaux et partage sécurisé.
+
+
+
+ {/* MODULE 3 : FACTURATION (FOSSBILLING) */}
+
+
EN ATTENTE
+
// Facturation
+
+ Centre de gestion FOSSBilling. Historique des paiements et renouvellement des baux réseau.
+
+
+
+ Solde Compte: 0.00 €
+
+
+ Prochaine Échéance: 12/07/2026
+
+
+
{ e.target.style.backgroundColor = '#FFB800'; e.target.style.color = '#000'; }}
+ onMouseOut={(e) => { e.target.style.backgroundColor = 'transparent'; e.target.style.color = '#FFB800'; }}>
+ Régler la facture
+
+
+
+
+
+ {/* --- TERMINAL DE LOGS (ESTHÉTIQUE SYSADMIN) --- */}
+
+
>_ SYSTEM_LOGS
+
+
[ OK ] Connexion chiffrée établie via TLS v1.3
+
[ OK ] Jetons d'authentification synchronisés avec FOSSBilling API
+
[ INFO ] Vérification des quotas de stockage Nextcloud... Terminée.
+
[ INFO ] 0 ticket(s) de support en attente.
+
> En attente d'instructions..._
+
+
+
+ {/* Animation CSS pour le curseur clignotant du terminal */}
+
+
);
}
\ No newline at end of file
diff --git a/src/pages/app/Services.jsx b/src/pages/app/Services.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/public/Home.jsx b/src/pages/public/Home.jsx
index 9a88624..8509464 100644
--- a/src/pages/public/Home.jsx
+++ b/src/pages/public/Home.jsx
@@ -14,7 +14,7 @@ export default function Home() {
{
- e.preventDefault(); // Empêche la page de se rafraîchir
+ e.preventDefault();
setError(null);
setLoading(true);
try {
- // On envoie la requête à FOSSBilling
- await loginClient(email, password);
-
- // Si on arrive ici, le login est un succès !
- // On redirige vers l'espace client sécurisé
- navigate('/dashboard');
-
+ // 1. APPEL À TON API BACKEND (FOSSBilling / PHP)
+ // Ici, tu mettras ton vrai 'fetch' vers ton serveur pour vérifier le mot de passe.
+ // Pour l'instant, on simule un délai réseau d'une seconde.
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ // --- SIMULATION D'AUTHENTIFICATION ---
+ // (À remplacer par la vraie validation de ton serveur)
+ if (email === 'test@gise.be' && password === 'Bunker!2026') {
+
+ // 2. LA CLÉ DU PROBLÈME EST ICI : L'ATTRIBUTION DU BADGE
+ // On sauvegarde le token (généralement renvoyé par ton API) dans le navigateur
+ localStorage.setItem('gise_token', 'secure_token_alphanumerique_factice');
+
+ // 3. AUTORISATION ET REDIRECTION
+ // Maintenant que le token est en poche, ProtectedRoute nous laissera passer !
+ navigate('/dashboard');
+
+ } else {
+ throw new Error("Accès refusé. Identifiants invalides ou signalement d'intrusion.");
+ }
+
} catch (err) {
- setError(err.message || "Accès refusé. Vérifiez vos identifiants.");
+ setError(err.message);
} finally {
setLoading(false);
}
};
- // Styles CSS en variables pour garder le code lisible
+ // --- DESIGN SYSTEM "BUNKER" ---
const inputStyle = {
- width: '100%', padding: '12px', marginBottom: '15px',
- backgroundColor: '#1A1A1A', color: '#00E5FF',
- border: '1px solid #333', fontFamily: 'monospace', outline: 'none'
+ width: '100%', padding: '10px', marginBottom: '20px',
+ backgroundColor: '#1A1A1A', color: '#00E5FF',
+ border: '1px solid #333', fontFamily: 'monospace', outline: 'none',
+ boxSizing: 'border-box'
};
const buttonStyle = {
width: '100%', padding: '12px', backgroundColor: loading ? '#333' : '#00E5FF',
color: loading ? '#888' : '#000', border: 'none', cursor: loading ? 'not-allowed' : 'pointer',
- fontFamily: 'monospace', fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: '1px'
+ fontFamily: 'monospace', fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: '1px',
+ marginTop: '10px'
};
return (
-
-
+
-
- Authentification
+
+ Connexion au Nexus
+
+ [ IDENTIFICATION REQUISE ]
+
- {/* Zone d'erreur qui s'affiche si le mot de passe est faux */}
{error && (
-
- [ ERREUR ] : {error}
+
+ [ ALERTE ] : {error}
)}
+
+
+
+ Aucun accès réseau ? S'enregistrer >
+
+
);
diff --git a/src/pages/public/Offres.jsx b/src/pages/public/Offres.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/public/Register.jsx b/src/pages/public/Register.jsx
index e0d2a7c..58c2d19 100644
--- a/src/pages/public/Register.jsx
+++ b/src/pages/public/Register.jsx
@@ -18,6 +18,21 @@ export default function Register() {
e.preventDefault();
setError(null);
+ // 1. DÉFINITION DE LA POLITIQUE DE MOT DE PASSE (Le Checkpoint)
+ // Explication de la Regex :
+ // (?=.*[a-z]) : Au moins une minuscule
+ // (?=.*[A-Z]) : Au moins une majuscule
+ // (?=.*\d) : Au moins un chiffre
+ // (?=.*[\W_]) : Au moins un caractère spécial (non-alphanumérique ou underscore)
+ // .{8,} : Minimum 8 caractères au total
+ const passwordPolicy = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/;
+
+ // 2. VÉRIFICATION
+ if (!passwordPolicy.test(password)) {
+ setError("ERREUR : Le mot de passe doit contenir 8 caractères min, une majuscule, une minuscule, un chiffre et un caractère spécial.");
+ return; // On stoppe l'exécution ici. La requête ne part pas vers le serveur.
+ }
+
// Sécurité Frontend : Validation des mots de passe avant envoi au serveur
if (password !== confirmPassword) {
setError("Les clés d'accès (mots de passe) ne correspondent pas.");
@@ -36,9 +51,9 @@ export default function Register() {
try {
// Envoi de la requête groupée à notre orchestrateur PHP backend
await registerUnifiedClient(email, username, password, firstName, lastName);
-
+
alert("[ PROVISIONNEMENT RÉUSSI ]\nVos comptes FOSSBilling, HestiaCP et Nextcloud ont été initialisés.\nVous pouvez maintenant vous connecter.");
-
+
// Redirection automatique vers la page de login après succès
navigate('/login');
} catch (err) {
@@ -50,8 +65,8 @@ export default function Register() {
// Réutilisation de ton Design System "Bunker"
const inputStyle = {
- width: '100%', padding: '10px', marginBottom: '15px',
- backgroundColor: '#1A1A1A', color: '#00E5FF',
+ width: '100%', padding: '10px', marginBottom: '15px',
+ backgroundColor: '#1A1A1A', color: '#00E5FF',
border: '1px solid #333', fontFamily: 'monospace', outline: 'none',
boxSizing: 'border-box'
};
@@ -65,8 +80,8 @@ export default function Register() {
return (
-
@@ -76,9 +91,17 @@ export default function Register() {
[ INITIALISATION DU PROVISIONNEMENT TRIPLE EN CASCADE ]
+ {/* Affichage des alertes système */}
{error && (
-
- [ ERREUR ] : {error}
+
+ [ ALERTE SYSTÈME ] : {error}
)}