ajout authentification admin/user

This commit is contained in:
AISSI-JUDE-CHRIST
2026-06-11 22:23:39 +02:00
parent 8f3451adc0
commit 4ae227d79d
7 changed files with 193 additions and 16 deletions
+48 -3
View File
@@ -1,14 +1,35 @@
import { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
import { getBookById } from '../api/books';
import { getBookById, reserveBook } from '../api/books';
import { useAuth } from '../context/AuthContext';
export default function BookDetail() {
const { bookId } = useParams();
const { user } = useAuth();
const { bookId } = useParams();
const [book, setBook] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [phoneNumber, setPhoneNumber] = useState('');
const [reservationStatus, setReservationStatus] = useState(null);
const [reserving, setReserving] = useState(false);
useEffect(() => {getBookById(bookId).then((response) => setBook(response.data)).catch((err) => {console.error(err);setError('Livre introuvable.');}).finally(() => setLoading(false));}, [bookId]);
useEffect(() => { getBookById(bookId).then((response) => setBook(response.data)).catch((err) => { console.error(err); setError('Livre introuvable.'); }).finally(() => setLoading(false)); }, [bookId]);
function handleReservation(e) {
e.preventDefault();
setReserving(true);
setReservationStatus(null);
reserveBook(bookId, { phoneNumber })
.then(() => {
setReservationStatus({ success: true, message: 'Réservation effectuée avec succès !' });
setPhoneNumber('');
})
.catch((err) => {
const msg = err.response?.data || 'Erreur lors de la réservation.';
setReservationStatus({ success: false, message: msg });
})
.finally(() => setReserving(false));
}
if (loading) return <main><p>Chargement</p></main>;
if (error) return <main><p>{error}</p><Link to="/books"> Retour au catalogue</Link></main>;
@@ -26,6 +47,30 @@ export default function BookDetail() {
<p>Langue : {book.language}</p>
<p>Catégories : {book.categories?.join(', ')}</p>
{book.description && <p>{book.description}</p>}
{user?.role === 'user' && <section>
<h2>Réserver ce livre</h2>
<form onSubmit={handleReservation}>
<label>
Numéro de téléphone :
<input
type="tel"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
placeholder="0612345678"
required
/>
</label>
<button type="submit" disabled={reserving}>
{reserving ? 'Réservation…' : 'Réserver'}
</button>
</form>
{reservationStatus && (
<p style={{ color: reservationStatus.success ? 'green' : 'red' }}>
{reservationStatus.message}
</p>
)}
</section>}
</main>
);
}
+3 -1
View File
@@ -1,8 +1,10 @@
import { useState, useEffect } from 'react';
import { getBooks } from '../api/books';
import { Link } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
export default function Books() {
const { user } = useAuth();
const [books, setBooks] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
@@ -28,7 +30,7 @@ export default function Books() {
return (
<main>
<h1>Catalogue</h1>
<Link to="/books/new">+ Ajouter un livre</Link>
{user?.role === 'admin' && <Link to="/books/new">+ Ajouter un livre</Link>}
<ul>
{books.map((book) => (
<li key={book.isbn}>
+57
View File
@@ -0,0 +1,57 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
export default function Login() {
const { login } = useAuth();
const navigate = useNavigate();
const [form, setForm] = useState({ username: '', password: '' });
const [error, setError] = useState(null);
function handleSubmit(e) {
e.preventDefault();
const ok = login(form.username, form.password);
if (ok) {
navigate('/');
} else {
setError('Identifiants incorrects.');
}
}
return (
<main>
<h1>Connexion</h1>
<form onSubmit={handleSubmit}>
<div>
<label>
Nom d'utilisateur :
<input
type="text"
value={form.username}
onChange={e => setForm(f => ({ ...f, username: e.target.value }))}
required
/>
</label>
</div>
<div>
<label>
Mot de passe :
<input
type="password"
value={form.password}
onChange={e => setForm(f => ({ ...f, password: e.target.value }))}
required
/>
</label>
</div>
<button type="submit">Se connecter</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</form>
<p>Comptes disponibles :</p>
<ul>
<li><strong>admin</strong> / admin (administrateur)</li>
<li><strong>user</strong> / user (utilisateur)</li>
</ul>
</main>
);
}