diff --git a/frontend/Design/image.png b/frontend/Design/image.png new file mode 100644 index 0000000..41aaeb4 Binary files /dev/null and b/frontend/Design/image.png differ diff --git a/frontend/src/pages/Connexion.jsx b/frontend/src/pages/Connexion.jsx index b6a25a0..7c75dea 100644 --- a/frontend/src/pages/Connexion.jsx +++ b/frontend/src/pages/Connexion.jsx @@ -1,73 +1,149 @@ import { useState } from 'react' -import { Link } from 'react-router-dom' +import { Link, useNavigate, useLocation } from 'react-router-dom' +import { loginApi } from '../services/auth' export default function Connexion() { + const navigate = useNavigate() + const location = useLocation() + const justRegistered = location.state?.registered === true const [form, setForm] = useState({ email: '', password: '' }) + const [showPassword, setShowPassword] = useState(false) + const [error, setError] = useState('') + const [loading, setLoading] = useState(false) const handleChange = (e) => setForm({ ...form, [e.target.name]: e.target.value }) - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault() - // TODO: connecter au backend - alert(`Connexion avec ${form.email}`) + setError('') + setLoading(true) + try { + const { token, user } = await loginApi(form) + localStorage.setItem('token', token) + localStorage.setItem('user', JSON.stringify(user)) + if (user.role === 'ADMIN') navigate('/admin') + else if (user.role === 'EMPLOYEE') navigate('/employe') + else navigate('/participation') + } catch (err) { + setError(err.message) + } finally { + setLoading(false) + } } return ( -
-
-
-

Thé Tip Top

-

Con - - nexion à votre espace

+
+ +
+

Se connecter

+

Connexion à votre espace

+
+ + {justRegistered && ( +
+ Compte créé avec succès ! Connectez-vous. +
+ )} + + {error && ( +
+ {error} +
+ )} + +
+ +
+ +
- -
- +
+ +
-
- -
- - +
+
+ +
+
- - + + -

- Pas encore de compte ?{' '} - - S'inscrire - -

+
+
+ Ou +
+ +
+ + +
+ +

+ Pas encore de compte ?{' '} + + S'inscrire + +

) } diff --git a/frontend/src/pages/Inscription.jsx b/frontend/src/pages/Inscription.jsx index 59af900..1f6ce7e 100644 --- a/frontend/src/pages/Inscription.jsx +++ b/frontend/src/pages/Inscription.jsx @@ -1,116 +1,175 @@ import { useState } from 'react' -import { Link } from 'react-router-dom' +import { Link, useNavigate } from 'react-router-dom' +import { registerApi } from '../services/auth' export default function Inscription() { + const navigate = useNavigate() const [form, setForm] = useState({ - firstName: '', - lastName: '', email: '', + lastName: '', + firstName: '', password: '', - acceptMarketing: false, }) + const [showPassword, setShowPassword] = useState(false) + const [error, setError] = useState('') + const [loading, setLoading] = useState(false) const handleChange = (e) => { - const { name, value, type, checked } = e.target - setForm({ ...form, [name]: type === 'checkbox' ? checked : value }) + const { name, value } = e.target + setForm({ ...form, [name]: value }) } - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault() - // TODO: connecter au backend - alert(`Inscription de ${form.firstName} ${form.lastName}`) + setError('') + setLoading(true) + try { + await registerApi({ + email: form.email, + firstname: form.firstName, + lastname: form.lastName, + password: form.password, + }) + navigate('/connexion', { state: { registered: true } }) + } catch (err) { + setError(err.message) + } finally { + setLoading(false) + } } return ( -
-
-
-

Thé Tip Top

-

Créer votre compte

+
+ +
+

S'inscrire

+

Créer votre compte

+
+ + {error && ( +
+ {error} +
+ )} + +
+ +
+ +
- -
-
- - -
-
- - -
-
+
+ + +
-
- - -
+
+ + +
-
- +
+ +
+
+
- + + - - - -

- Déjà un compte ?{' '} - - Se connecter - -

+
+
+ Ou +
+ +
+ + +
+ +

+ Vous avez déjà un compte ?{' '} + + Se connecter + +

) } diff --git a/frontend/src/services/auth.js b/frontend/src/services/auth.js new file mode 100644 index 0000000..b251768 --- /dev/null +++ b/frontend/src/services/auth.js @@ -0,0 +1,23 @@ +const BASE = '/api/auth' + +export async function loginApi({ email, password }) { + const res = await fetch(`${BASE}/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }), + }) + const data = await res.json() + if (!res.ok) throw new Error(data.message || 'Erreur de connexion.') + return data +} + +export async function registerApi({ email, firstname, lastname, password }) { + const res = await fetch(`${BASE}/register`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, firstname, lastname, password }), + }) + const data = await res.json() + if (!res.ok) throw new Error(data.message || "Erreur lors de l'inscription.") + return data +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 0616e59..619db35 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -4,4 +4,9 @@ import tailwindcss from '@tailwindcss/vite' export default defineConfig({ plugins: [react(), tailwindcss()], + server: { + proxy: { + '/api': 'http://localhost:5000', + }, + }, })