groupe-meditation/frontend/src/pages/Login.jsx

94 lines
3.1 KiB
React
Raw Normal View History

2026-03-04 14:01:00 -05:00
import React, { useState, useEffect } from 'react';
import { useStore } from '../stores/store';
export default function Login() {
const { login, loading, error, groupes, loadGroupes, setPage } = useStore();
const [prenom, setPrenom] = useState('');
const [pin, setPin] = useState('');
const [groupeId, setGroupeId] = useState('');
useEffect(() => {
if (groupes.length === 0) loadGroupes();
}, []);
useEffect(() => {
if (groupes.length === 1) setGroupeId(groupes[0].id);
}, [groupes]);
const handleSubmit = async (e) => {
e.preventDefault();
if (!prenom || !pin || !groupeId) return;
try {
await login(prenom, pin, groupeId);
} catch {}
};
return (
<div className="min-h-screen bg-gradient-to-b from-aa-blue to-blue-900 flex flex-col items-center justify-center p-6">
<div className="text-center mb-8">
<div className="text-5xl mb-3">☮️</div>
<h1 className="text-2xl font-bold text-white">Groupe Méditation</h1>
<p className="text-blue-200 text-sm mt-1">District 87-16 · Région 87</p>
</div>
<form onSubmit={handleSubmit} className="w-full max-w-sm bg-white rounded-2xl shadow-xl p-6 space-y-4">
{groupes.length > 1 && (
<select
value={groupeId}
onChange={(e) => setGroupeId(e.target.value)}
className="w-full p-4 bg-gray-50 rounded-xl text-lg border-0 focus:ring-2 focus:ring-aa-blue"
>
<option value="">Choisir le groupe</option>
{groupes.map((g) => (
<option key={g.id} value={g.id}>{g.nom}</option>
))}
</select>
)}
<input
type="text"
placeholder="Prénom"
value={prenom}
onChange={(e) => setPrenom(e.target.value)}
className="w-full p-4 bg-gray-50 rounded-xl text-lg border-0 focus:ring-2 focus:ring-aa-blue"
autoComplete="off"
autoCapitalize="words"
/>
<input
type="password"
inputMode="numeric"
pattern="[0-9]*"
maxLength={4}
placeholder="PIN (4 chiffres)"
value={pin}
onChange={(e) => setPin(e.target.value.replace(/\D/g, '').slice(0, 4))}
className="w-full p-4 bg-gray-50 rounded-xl text-lg text-center tracking-[1em] border-0 focus:ring-2 focus:ring-aa-blue"
/>
{error && (
<p className="text-red-500 text-sm text-center bg-red-50 p-3 rounded-lg">{error}</p>
)}
<button
type="submit"
disabled={loading || !prenom || pin.length !== 4 || !groupeId}
className="w-full p-4 bg-aa-blue text-white rounded-xl text-lg font-bold disabled:opacity-40 active:scale-[0.97] transition"
>
{loading ? '...' : 'Connexion'}
</button>
<button
type="button"
onClick={() => setPage('inscription')}
className="w-full p-3 text-aa-blue text-sm font-medium"
>
J'ai un code d'invitation →
</button>
</form>
<p className="text-blue-300 text-xs mt-6">100% logiciel libre · Hébergé au Québec</p>
</div>
);
}