You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
6.5 KiB
131 lines
6.5 KiB
import React, { useState } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { useAuth } from '../contexts/AuthContext';
|
|
import Navbar from '../components/Navbar';
|
|
import GitHubLoginButton from '../components/GitHubLoginButton';
|
|
|
|
export default function Login() {
|
|
const [formData, setFormData] = useState({
|
|
username: '',
|
|
password: ''
|
|
});
|
|
const [alerts, setAlerts] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
|
|
const navigate = useNavigate();
|
|
const { login } = useAuth();
|
|
|
|
const handleChange = (e) => {
|
|
setFormData({
|
|
...formData,
|
|
[e.target.name]: e.target.value
|
|
});
|
|
};
|
|
|
|
const addAlert = (type, message) => {
|
|
const newAlert = { type, message, id: Date.now() };
|
|
setAlerts([...alerts, newAlert]);
|
|
};
|
|
|
|
const onCloseAlert = (alertToRemove) => {
|
|
setAlerts(alerts.filter(alert => alert !== alertToRemove));
|
|
};
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
setAlerts([]);
|
|
setLoading(true);
|
|
|
|
try {
|
|
await login(formData.username, formData.password);
|
|
navigate('/');
|
|
} catch (err) {
|
|
addAlert('error', err.message || 'Erreur de connexion');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
|
|
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} />
|
|
|
|
<div className="flex justify-center items-center min-h-screen pt-20">
|
|
<div className="glassmorphism p-8 rounded-lg shadow-lg w-full max-w-md">
|
|
<h2 className="text-3xl font-bold text-center mb-6 font-montserrat text-white">Connexion</h2>
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div>
|
|
<label htmlFor="username" className="block text-sm font-medium text-white mb-1">
|
|
Nom d'utilisateur
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="username"
|
|
name="username"
|
|
value={formData.username}
|
|
onChange={handleChange}
|
|
required
|
|
className="w-full px-3 py-2 glassmorphism text-white rounded-md focus:outline-none"
|
|
placeholder="Entrez votre nom d'utilisateur"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label htmlFor="password" className="block text-sm font-medium text-white mb-1">
|
|
Mot de passe
|
|
</label>
|
|
<div className='w-full glassmorphism flex items-center'>
|
|
<input
|
|
type={showPassword ? "text" : "password"}
|
|
id="password"
|
|
name="password"
|
|
value={formData.password}
|
|
onChange={handleChange}
|
|
required
|
|
className="flex-1 px-3 py-2 focus:outline-none text-white"
|
|
placeholder="Entrez votre mot de passe"
|
|
/>
|
|
<button
|
|
type="button"
|
|
onClick={() => setShowPassword(!showPassword)}
|
|
className="absolute right-3 top-1/2 transform -translate-y-1/2"
|
|
>
|
|
{showPassword ? (
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" className='fill-white' viewBox="0 0 24 24" >
|
|
<path d="M12 9a3 3 0 1 0 0 6 3 3 0 1 0 0-6"></path><path d="M12 19c7.63 0 9.93-6.62 9.95-6.68.07-.21.07-.43 0-.63-.02-.07-2.32-6.68-9.95-6.68s-9.93 6.61-9.95 6.67c-.07.21-.07.43 0 .63.02.07 2.32 6.68 9.95 6.68Zm0-12c5.35 0 7.42 3.85 7.93 5-.5 1.16-2.58 5-7.93 5s-7.42-3.84-7.93-5c.5-1.16 2.58-5 7.93-5"></path>
|
|
</svg>
|
|
) : (
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className='fill-white' >
|
|
<path d="M12 17c-5.35 0-7.42-3.84-7.93-5 .2-.46.65-1.34 1.45-2.23l-1.4-1.4c-1.49 1.65-2.06 3.28-2.08 3.31-.07.21-.07.43 0 .63.02.07 2.32 6.68 9.95 6.68.91 0 1.73-.1 2.49-.26l-1.77-1.77c-.24.02-.47.03-.72.03ZM21.95 12.32c.07-.21.07-.43 0-.63-.02-.07-2.32-6.68-9.95-6.68-1.84 0-3.36.39-4.61.97L2.71 1.29 1.3 2.7l4.32 4.32 1.42 1.42 2.27 2.27 3.98 3.98 1.8 1.8 1.53 1.53 4.68 4.68 1.41-1.41-4.32-4.32c2.61-1.95 3.55-4.61 3.56-4.65m-7.25.97c.19-.39.3-.83.3-1.29 0-1.64-1.36-3-3-3-.46 0-.89.11-1.29.3l-1.8-1.8c.88-.31 1.9-.5 3.08-.5 5.35 0 7.42 3.85 7.93 5-.3.69-1.18 2.33-2.96 3.55z"></path>
|
|
</svg>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 font-montserrat"
|
|
>
|
|
{loading ? 'Connexion...' : 'Se connecter'}
|
|
</button>
|
|
<GitHubLoginButton className="mt-1 cursor-pointer" />
|
|
</form>
|
|
|
|
<div className="mt-6 text-center">
|
|
<p className="text-gray-600">
|
|
Pas encore de compte ?{' '}
|
|
<a href="/register" className="text-blue-600 hover:underline">
|
|
Créer un compte
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|