init projet

This commit is contained in:
2026-05-20 10:43:18 +02:00
parent 51f27903bb
commit 9a402b0b34
57 changed files with 5622 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
/* Page de connexion : formulaire + SSO Windows */
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../context/AuthContext';
import { getHealth } from '../../services/api';
import styles from './Login.module.css';
export default function Login() {
const [identifiant, setIdentifiant] = useState('');
const [motDePasse, setMotDePasse] = useState('');
const [loading, setLoading] = useState(false);
const [erreur, setErreur] = useState('');
const { login } = useAuth();
const navigate = useNavigate();
async function handleSubmit(e) {
e.preventDefault();
setErreur('');
setLoading(true);
try {
/* Vérification de la disponibilité de l'API avant connexion */
await getHealth();
login({ nom: identifiant || 'Utilisateur', role: 'user', token: 'session' });
navigate('/dashboard');
} catch {
setErreur('Impossible de contacter le serveur. Vérifiez que l\'API est démarrée sur le port 8000.');
} finally {
setLoading(false);
}
}
function handleSso() {
/* Connexion SSO Windows : même vérification API */
handleSubmit({ preventDefault: () => {} });
}
return (
<div className={styles.page}>
<div className={styles.card}>
<div className={styles.logoArea}>
<span className={styles.logoIcon}></span>
<h1 className={styles.logoText}>Data Sentinel</h1>
<p className={styles.byXefi}>by XEFI</p>
</div>
<form className={styles.form} onSubmit={handleSubmit}>
<div className={styles.field}>
<label className={styles.label} htmlFor="identifiant">Identifiant</label>
<input
id="identifiant"
type="text"
className={styles.input}
value={identifiant}
onChange={e => setIdentifiant(e.target.value)}
placeholder="Votre identifiant"
autoComplete="username"
/>
</div>
<div className={styles.field}>
<label className={styles.label} htmlFor="motDePasse">Mot de passe</label>
<input
id="motDePasse"
type="password"
className={styles.input}
value={motDePasse}
onChange={e => setMotDePasse(e.target.value)}
placeholder="••••••••"
autoComplete="current-password"
/>
</div>
{erreur && <p className={styles.erreur}>{erreur}</p>}
<button type="submit" className={styles.btnPrimary} disabled={loading}>
{loading ? 'Connexion...' : 'Se connecter'}
</button>
</form>
<div className={styles.divider}>
<span>ou</span>
</div>
<button type="button" className={styles.btnSecondary} onClick={handleSso} disabled={loading}>
Connexion Windows SSO
</button>
<div className={styles.links}>
<a href="#" className={styles.forgotLink}>Mot de passe oublié ?</a>
</div>
</div>
</div>
);
}