ajout du dashboard
Deploy Nexus Portal to HestiaCP (FTP) / build-and-deploy (push) Successful in 16s

This commit is contained in:
maximus
2026-06-12 15:53:16 +02:00
parent cab5d749d2
commit bfa3161646
10 changed files with 400 additions and 195 deletions
+56 -29
View File
@@ -1,6 +1,6 @@
// src/pages/public/Login.jsx
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { loginClient } from '../../services/api';
import { useNavigate, Link } from 'react-router-dom';
export default function Login() {
const [email, setEmail] = useState('');
@@ -10,80 +10,107 @@ export default function Login() {
const navigate = useNavigate();
const handleLogin = async (e) => {
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 (
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '10vh' }}>
<div style={{
width: '100%', maxWidth: '400px', backgroundColor: '#242424',
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '10vh', padding: '0 20px' }}>
<div style={{
width: '100%', maxWidth: '400px', backgroundColor: '#242424',
padding: '30px', borderTop: '4px solid #00E5FF', boxShadow: '0 10px 30px rgba(0,0,0,0.5)'
}}>
<h2 style={{ color: '#FFF', textTransform: 'uppercase', marginBottom: '20px', fontSize: '1.5rem' }}>
Authentification
<h2 style={{ color: '#FFF', textTransform: 'uppercase', marginBottom: '5px', fontSize: '1.5rem', textAlign: 'center' }}>
Connexion au Nexus
</h2>
<p style={{ color: '#888', fontFamily: 'monospace', fontSize: '0.85rem', marginBottom: '25px', textAlign: 'center' }}>
[ IDENTIFICATION REQUISE ]
</p>
{/* Zone d'erreur qui s'affiche si le mot de passe est faux */}
{error && (
<div style={{ backgroundColor: 'rgba(255, 68, 68, 0.1)', color: '#FF4444', padding: '10px', marginBottom: '15px', border: '1px solid #FF4444', fontSize: '0.9rem' }}>
[ ERREUR ] : {error}
<div style={{
color: '#ff003c', border: '1px solid #ff003c', backgroundColor: 'rgba(255, 0, 60, 0.1)',
padding: '10px', marginBottom: '20px', fontFamily: 'monospace', fontSize: '0.85rem'
}}>
[ ALERTE ] : {error}
</div>
)}
<form onSubmit={handleLogin}>
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>IDENTIFIANT (EMAIL)</label>
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>IDENTIFIANT (E-MAIL)</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
style={inputStyle}
required
placeholder="admin@gise.be"
placeholder="admin@gise.be"
/>
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>CLÉ D'ACCÈS (MOT DE PASSE)</label>
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>CLÉ D'ACCÈS SÉCURISÉE</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
style={inputStyle}
required
placeholder="••••••••"
placeholder="••••••••"
/>
<button type="submit" style={buttonStyle} disabled={loading}>
{loading ? 'VÉRIFICATION...' : 'INITIALISER LA CONNEXION'}
{loading ? 'VÉRIFICATION...' : 'OUVRIR LE SAS'}
</button>
</form>
<div style={{ marginTop: '20px', textAlign: 'center', fontSize: '0.85rem' }}>
<Link to="/register" style={{ color: '#888', textDecoration: 'none' }}>
Aucun accès réseau ? <span style={{ color: '#00E5FF' }}>S'enregistrer &gt;</span>
</Link>
</div>
</div>
</div>
);