upgrade design
This commit is contained in:
@@ -3,9 +3,6 @@ import { useNavigate, Link } from 'react-router-dom';
|
||||
import { registerUnifiedClient } from '../../services/api';
|
||||
import NotificationModal from '../../components/ui/NotificationModal';
|
||||
|
||||
// ============================================================================
|
||||
// COMPOSANT PRINCIPAL : REGISTER
|
||||
// ============================================================================
|
||||
export default function Register() {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
@@ -15,7 +12,7 @@ export default function Register() {
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [customAlert, setCustomAlert] = useState(null); // Remplace l'état "error" et "alert()"
|
||||
const [customAlert, setCustomAlert] = useState(null);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleRegister = async (e) => {
|
||||
@@ -23,119 +20,81 @@ export default function Register() {
|
||||
setCustomAlert(null);
|
||||
|
||||
const passwordPolicy = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/;
|
||||
|
||||
// VÉRIFICATIONS FRONTEND (Affiche le Modal d'Erreur)
|
||||
if (!passwordPolicy.test(password)) {
|
||||
setCustomAlert({ type: 'error', title: 'Sécurité compromise', message: "Le mot de passe doit contenir 8 caractères min, une majuscule, une minuscule, un chiffre et un caractère spécial." });
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
setCustomAlert({ type: 'error', title: 'Erreur de saisie', message: "Les clés d'accès (mots de passe) ne correspondent pas." });
|
||||
setCustomAlert({ type: 'error', title: 'Erreur de saisie', message: "Les clés d'accès ne correspondent pas." });
|
||||
return;
|
||||
}
|
||||
|
||||
const validUsername = /^[a-zA-Z0-9]{3,12}$/.test(username);
|
||||
if (!validUsername) {
|
||||
setCustomAlert({ type: 'error', title: 'Identifiant invalide', message: "Le nom d'utilisateur doit contenir uniquement des lettres ou chiffres (entre 3 et 12 caractères, sans espace)." });
|
||||
if (!/^[a-zA-Z0-9]{3,12}$/.test(username)) {
|
||||
setCustomAlert({ type: 'error', title: 'Identifiant invalide', message: "Le nom d'utilisateur doit contenir uniquement des lettres ou chiffres (entre 3 et 12 caractères)." });
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
// API BACKEND
|
||||
await registerUnifiedClient(email, username, password, firstName, lastName);
|
||||
|
||||
// SUCCÈS (Affiche le Modal de Succès)
|
||||
setCustomAlert({
|
||||
type: 'success',
|
||||
title: 'PROVISIONNEMENT RÉUSSI',
|
||||
message: "Vos comptes FOSSBilling, HestiaCP et Nextcloud ont été initialisés.\n\nVous pouvez maintenant vous connecter à l'infrastructure."
|
||||
});
|
||||
|
||||
setCustomAlert({ type: 'success', title: 'PROVISIONNEMENT RÉUSSI', message: "Vos comptes FOSSBilling, HestiaCP et Nextcloud ont été initialisés.\n\nVous pouvez maintenant vous connecter." });
|
||||
} catch (err) {
|
||||
// ERREUR API (Affiche le Modal d'Erreur API)
|
||||
setCustomAlert({ type: 'error', title: 'Échec du Déploiement', message: err.message || "Échec de l'initialisation de l'infrastructure." });
|
||||
setCustomAlert({ type: 'error', title: 'Échec du Déploiement', message: err.message || "Échec de l'initialisation." });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Fermeture du Modal : Redirige vers le Login SI c'était un succès
|
||||
const handleCloseModal = () => {
|
||||
if (customAlert?.type === 'success') {
|
||||
navigate('/login');
|
||||
} else {
|
||||
setCustomAlert(null);
|
||||
}
|
||||
};
|
||||
|
||||
// Styles
|
||||
const inputStyle = {
|
||||
width: '100%', padding: '10px', marginBottom: '15px',
|
||||
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',
|
||||
marginTop: '10px'
|
||||
if (customAlert?.type === 'success') navigate('/login');
|
||||
else setCustomAlert(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '5vh', padding: '0 20px' }}>
|
||||
<div style={{
|
||||
width: '100%', maxWidth: '500px', 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: '5px', fontSize: '1.5rem' }}>
|
||||
<div className="flex justify-center mt-[5vh] px-5">
|
||||
<div className="w-full max-w-[500px] bg-[#242424] p-8 border-t-4 border-cyan-400 shadow-[0_10px_30px_rgba(0,0,0,0.5)]">
|
||||
<h2 className="text-white uppercase mb-1 text-2xl font-sans font-bold">
|
||||
Créer un accès réseau
|
||||
</h2>
|
||||
<p style={{ color: '#888', fontFamily: 'monospace', fontSize: '0.85rem', marginBottom: '25px' }}>
|
||||
[ INITIALISATION DU PROVISIONNEMENT TRIPLE EN CASCADE ]
|
||||
<p className="text-[#888] font-mono text-sm mb-6">
|
||||
[ INITIALISATION DU PROVISIONNEMENT TRIPLE ]
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleRegister}>
|
||||
<div style={{ display: 'flex', gap: '15px' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>PRÉNOM</label>
|
||||
<input type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} style={inputStyle} required placeholder="John" />
|
||||
<form onSubmit={handleRegister} className="font-mono">
|
||||
<div className="flex gap-4">
|
||||
<div className="flex-1">
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">Prénom</label>
|
||||
<input type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} required placeholder="John" className="w-full p-3 mb-4 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>NOM</label>
|
||||
<input type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} style={inputStyle} required placeholder="Doe" />
|
||||
<div className="flex-1">
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">Nom</label>
|
||||
<input type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} required placeholder="Doe" className="w-full p-3 mb-4 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>ADRESSE E-MAIL (IDENTIFIANT FACTURATION)</label>
|
||||
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} style={inputStyle} required placeholder="john.doe@gise.be" />
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">E-mail (Facturation)</label>
|
||||
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required placeholder="john.doe@gise.be" className="w-full p-3 mb-4 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>NOM D'UTILISATEUR SÉCURISÉ (ACCÈS HESTIA & CLOUD)</label>
|
||||
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} style={inputStyle} required placeholder="ex: jdoe42" />
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">Identifiant sécurisé (Cloud)</label>
|
||||
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} required placeholder="ex: jdoe42" className="w-full p-3 mb-4 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>CLÉ D'ACCÈS (MOT DE PASSE UNIQUE)</label>
|
||||
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} style={inputStyle} required placeholder="••••••••" />
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">Clé d'accès unique</label>
|
||||
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required placeholder="••••••••" className="w-full p-3 mb-4 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
|
||||
<label style={{ display: 'block', color: '#888', marginBottom: '5px', fontSize: '0.8rem' }}>CONFIRMER LA CLÉ D'ACCÈS</label>
|
||||
<input type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} style={inputStyle} required placeholder="••••••••" />
|
||||
<label className="block text-[#888] mb-1 text-xs tracking-widest uppercase">Confirmer la clé</label>
|
||||
<input type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} required placeholder="••••••••" className="w-full p-3 mb-5 bg-[#1A1A1A] text-cyan-400 border border-[#333] outline-none focus:border-cyan-400 transition-colors" />
|
||||
|
||||
<button type="submit" style={buttonStyle} disabled={loading}>
|
||||
<button type="submit" disabled={loading} className="w-full p-3 mt-2 font-bold uppercase tracking-widest transition-colors disabled:bg-[#333] disabled:text-[#888] disabled:cursor-not-allowed bg-cyan-400 hover:bg-cyan-300 text-black shadow-[0_0_15px_rgba(0,229,255,0.2)]">
|
||||
{loading ? 'DÉPLOIEMENT EN COURS...' : 'LANCER LE PROVISIONNEMENT'}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div style={{ marginTop: '20px', textAlign: 'center', fontSize: '0.85rem' }}>
|
||||
<Link to="/login" style={{ color: '#888', textDecoration: 'none' }}>
|
||||
Déjà enregistré ? <span style={{ color: '#00E5FF' }}>Se connecter au terminal ></span>
|
||||
<div className="mt-5 text-center text-sm font-mono text-[#888]">
|
||||
Déjà enregistré ?{' '}
|
||||
<Link to="/login" className="text-cyan-400 hover:text-cyan-300 transition-colors no-underline">
|
||||
Se connecter au terminal >
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Affichage du Modal par-dessus le formulaire */}
|
||||
<NotificationModal notification={customAlert} onClose={handleCloseModal} />
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user