Enregistrer un livre #2

Merged
Adrien DICK merged 1 commits from EnregistrerLivre into main 2026-06-11 11:35:24 +02:00
4 changed files with 113 additions and 0 deletions
+2
View File
@@ -5,6 +5,7 @@ import Books from './pages/Books';
import Orders from './pages/Orders'; import Orders from './pages/Orders';
import Profile from './pages/Profile'; import Profile from './pages/Profile';
import NotFound from './pages/NotFound'; import NotFound from './pages/NotFound';
import AddBook from './pages/AddBook';
export default function App() { export default function App() {
return ( return (
@@ -15,6 +16,7 @@ export default function App() {
<Route path="orders" element={<Orders />} /> <Route path="orders" element={<Orders />} />
<Route path="profile" element={<Profile />} /> <Route path="profile" element={<Profile />} />
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
<Route path="books/new" element={<AddBook />} />
</Route> </Route>
</Routes> </Routes>
); );
+4
View File
@@ -2,4 +2,8 @@ import client from './client';
export function getBooks(page = 0, size = 20) { export function getBooks(page = 0, size = 20) {
return client.get('/api/books', { params: { page, size } }); return client.get('/api/books', { params: { page, size } });
}
export function registerBook(book) {
return client.post('/api/books', book);
} }
+105
View File
@@ -0,0 +1,105 @@
import { useState } from 'react';
import { registerBook } from '../api/books';
const CATEGORIES = ['FICTION', 'NON_FICTION', 'SCIENCE_FICTION', 'FANTASY', 'MYSTERY', 'THRILLER', 'ROMANCE', 'BIOGRAPHY', 'HISTORY', 'POETRY', 'CHILDRENS', 'YOUNG_ADULT', 'SCIENCE', 'PHILOSOPHY', 'SELF_HELP', 'TRAVEL', 'COOKING', 'ART', 'RELIGION', 'REFERENCE'];
const initialForm = {
isbn: '', title: '', author: '', publisher: '', publicationDate: '', price: '', quantity: '', categories: [], description: '', language: '',
};
export default function AddBook() {
const [form, setForm] = useState(initialForm);
const [message, setMessage] = useState(null);
const [submitting, setSubmitting] = useState(false);
function handleChange(e) {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
}
function handleCategoryChange(e) {
setForm((prev) => ({ ...prev, categories: e.target.value ? [e.target.value] : [] }));
}
function handleSubmit(e) {
e.preventDefault();
setSubmitting(true);
setMessage(null);
const payload = {
...form,
isbn: Number(form.isbn),
price: Number(form.price),
quantity: Number(form.quantity),
};
registerBook(payload)
.then((response) => {
setMessage({ type: 'success', text: `Livre créé (id : ${response.data}) ✅` });
setForm(initialForm);
})
.catch((error) => {
console.error(error);
const status = error.response?.status;
if (status === 406) setMessage({ type: 'error', text: 'Ce livre existe déjà.' });
else if (status === 400) setMessage({ type: 'error', text: 'Données invalides, vérifie les champs.' });
else setMessage({ type: 'error', text: 'Erreur lors de la création.' });
})
.finally(() => setSubmitting(false));
}
return (
<main>
<h1>Ajouter un livre</h1>
<form onSubmit={handleSubmit}>
<table>
<tr>
<td>ISBN</td>
<td><input name="isbn" type="number" value={form.isbn} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Titre</td>
<td><input name="title" value={form.title} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Auteur</td>
<td><input name="author" value={form.author} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Éditeur</td>
<td><input name="publisher" value={form.publisher} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Date de publication</td>
<td><input name="publicationDate" type="date" value={form.publicationDate} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Prix</td>
<td><input name="price" type="number" step="0.01" value={form.price} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Quantité</td>
<td><input name="quantity" type="number" value={form.quantity} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Langue</td>
<td><input name="language" value={form.language} onChange={handleChange} required /></td>
</tr>
<tr>
<td>Catégorie</td>
<td><select value={form.categories[0] || ''} onChange={handleCategoryChange} required><option value=""> choisir </option>{CATEGORIES.map((c) => <option key={c} value={c}>{c}</option>)}</select></td>
</tr>
<tr>
<td>Description</td>
<td><textarea name="description" value={form.description} onChange={handleChange} /></td>
</tr>
</table>
<button type="submit" disabled={submitting}>
{submitting ? 'Envoi…' : 'Ajouter le livre'}
</button>
</form>
{message && <p>{message.text}</p>}
</main>
);
}
+2
View File
@@ -1,5 +1,6 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { getBooks } from '../api/books'; import { getBooks } from '../api/books';
import { Link } from 'react-router-dom';
export default function Books() { export default function Books() {
const [books, setBooks] = useState([]); const [books, setBooks] = useState([]);
@@ -27,6 +28,7 @@ export default function Books() {
return ( return (
<main> <main>
<h1>Catalogue</h1> <h1>Catalogue</h1>
<Link to="/books/new">+ Ajouter un livre</Link>
<ul> <ul>
{books.map((book) => ( {books.map((book) => (
<li key={book.isbn}> <li key={book.isbn}>