authentification nocodebackend ok
This commit is contained in:
105
components/LoginPage.tsx
Normal file
105
components/LoginPage.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useAuthContext } from '../AuthContext';
|
||||
import { Loader2, AlertCircle, ArrowRight } from 'lucide-react';
|
||||
|
||||
interface LoginPageProps {
|
||||
onSuccess: () => void;
|
||||
onRegister: () => void;
|
||||
}
|
||||
|
||||
const LoginPage: React.FC<LoginPageProps> = ({ onSuccess, onRegister }) => {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Use the global auth context
|
||||
const { login } = useAuthContext();
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const result = await login({ email, password });
|
||||
|
||||
if (result && result.error) {
|
||||
setError(result.error);
|
||||
setLoading(false);
|
||||
} else {
|
||||
onSuccess();
|
||||
}
|
||||
} catch (err) {
|
||||
setError("Une erreur inattendue est survenue.");
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50 flex overflow-hidden font-sans text-slate-900 items-center justify-center p-4">
|
||||
{/* Using styles similar to AuthPage for consistency */}
|
||||
<div className="w-full max-w-md bg-white rounded-2xl shadow-xl overflow-hidden p-8 animate-in fade-in zoom-in duration-300">
|
||||
<div className="text-center mb-8">
|
||||
<h1 className="text-3xl font-black text-slate-900 mb-2">Connexion</h1>
|
||||
<p className="text-slate-500">Bienvenue ! Connectez-vous à votre compte</p>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="mb-6 p-4 bg-red-50 border border-red-100 text-red-600 text-sm font-medium rounded-xl flex items-center gap-2 animate-in shake duration-300">
|
||||
<AlertCircle size={18} />
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-black text-slate-500 uppercase tracking-widest ml-1" htmlFor="email">Email</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500 font-medium transition-all"
|
||||
placeholder="votre@email.com"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-black text-slate-500 uppercase tracking-widest ml-1" htmlFor="password">Mot de passe</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500 font-medium transition-all"
|
||||
placeholder="••••••••"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full bg-slate-900 text-white py-4 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-blue-600 transition-all shadow-xl disabled:opacity-50 mt-6"
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? <Loader2 className="animate-spin" /> : "Se connecter"} <ArrowRight size={18} />
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="mt-8 text-center text-sm text-slate-500">
|
||||
Pas encore de compte ?{" "}
|
||||
<button
|
||||
onClick={onRegister}
|
||||
className="font-bold text-blue-600 hover:text-blue-800 transition-colors ml-1"
|
||||
>
|
||||
Créer un compte
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoginPage;
|
||||
Reference in New Issue
Block a user