diff --git a/my-library/src/App.jsx b/my-library/src/App.jsx index a10b954..7a4a919 100644 --- a/my-library/src/App.jsx +++ b/my-library/src/App.jsx @@ -9,6 +9,7 @@ import AddBook from './pages/AddBook'; import BookDetail from './pages/BookDetail'; import Customers from './pages/Customers'; import Login from './pages/Login'; +import Reservations from './pages/Reservations'; import { useAuth } from './context/AuthContext'; function RequireAuth({ children }) { @@ -33,6 +34,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/my-library/src/components/Navbar.jsx b/my-library/src/components/Navbar.jsx index 84dce88..882960c 100644 --- a/my-library/src/components/Navbar.jsx +++ b/my-library/src/components/Navbar.jsx @@ -19,6 +19,7 @@ export default function Navbar() {
  • Accueil
  • Catalogue
  • {user &&
  • Commandes
  • } + {user?.role === 'user' &&
  • Mes réservations
  • } {user &&
  • Mon compte
  • } {user?.role === 'admin' &&
  • Clients
  • } diff --git a/my-library/src/context/ReservationContext.js b/my-library/src/context/ReservationContext.js new file mode 100644 index 0000000..7d22c65 --- /dev/null +++ b/my-library/src/context/ReservationContext.js @@ -0,0 +1,42 @@ +import { createContext, useContext, useState } from 'react'; + +const ReservationContext = createContext(null); + +export function ReservationProvider({ children }) { + const [reservations, setReservations] = useState(() => { + const saved = localStorage.getItem('reservations'); + return saved ? JSON.parse(saved) : []; + }); + + function addReservation(book, phoneNumber) { + const reservation = { + reservationId: crypto.randomUUID(), + bookId: book.isbn, + bookTitle: book.title, + bookAuthor: book.author, + phoneNumber, + status: 'CONFIRMED', + reservedAt: new Date().toISOString(), + }; + const updated = [...reservations, reservation]; + setReservations(updated); + localStorage.setItem('reservations', JSON.stringify(updated)); + return reservation; + } + + function cancelReservation(reservationId) { + const updated = reservations.filter(r => r.reservationId !== reservationId); + setReservations(updated); + localStorage.setItem('reservations', JSON.stringify(updated)); + } + + return ( + + {children} + + ); +} + +export function useReservations() { + return useContext(ReservationContext); +} diff --git a/my-library/src/index.js b/my-library/src/index.js index 71c19cb..451e262 100644 --- a/my-library/src/index.js +++ b/my-library/src/index.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import { AuthProvider } from './context/AuthContext'; +import { ReservationProvider } from './context/ReservationContext'; import App from './App'; import './styles/global.css'; @@ -10,7 +11,9 @@ root.render( - + + + diff --git a/my-library/src/pages/BookDetail.jsx b/my-library/src/pages/BookDetail.jsx index 77cf45c..ca937e9 100644 --- a/my-library/src/pages/BookDetail.jsx +++ b/my-library/src/pages/BookDetail.jsx @@ -1,34 +1,26 @@ import { useState, useEffect } from 'react'; import { useParams, Link } from 'react-router-dom'; -import { getBookById, reserveBook } from '../api/books'; +import { getBookById } from '../api/books'; import { useAuth } from '../context/AuthContext'; +import { useReservations } from '../context/ReservationContext'; export default function BookDetail() { const { user } = useAuth(); + const { addReservation } = useReservations(); 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]); 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)); + addReservation(book, phoneNumber); + setReservationStatus({ success: true, message: 'Réservation effectuée avec succès !' }); + setPhoneNumber(''); } if (loading) return

    Chargement…

    ; @@ -61,9 +53,7 @@ export default function BookDetail() { required /> - + {reservationStatus && (

    diff --git a/my-library/src/pages/Reservations.jsx b/my-library/src/pages/Reservations.jsx new file mode 100644 index 0000000..3bf535a --- /dev/null +++ b/my-library/src/pages/Reservations.jsx @@ -0,0 +1,37 @@ +import { useReservations } from '../context/ReservationContext'; +import { Link } from 'react-router-dom'; + +export default function Reservations() { + const { reservations, cancelReservation } = useReservations(); + + if (reservations.length === 0) { + return ( +

    +

    Mes réservations

    +

    Aucune réservation pour le moment.

    + ← Retour au catalogue +
    + ); + } + + return ( +
    +

    Mes réservations

    +
      + {reservations.map(r => ( +
    • + {r.bookTitle} — {r.bookAuthor} +
      + Téléphone : {r.phoneNumber} +
      + Réservé le : {new Date(r.reservedAt).toLocaleDateString('fr-FR')} +
      + Statut : {r.status} +
      + +
    • + ))} +
    +
    + ); +}