добавил поиск по названию и вернул филтрацию
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -15,8 +15,8 @@ function App() {
|
|||||||
const [authors] = useState(data.authors);
|
const [authors] = useState(data.authors);
|
||||||
const [statuses] = useState(data.statuses);
|
const [statuses] = useState(data.statuses);
|
||||||
const [editingBook, setEditingBook] = useState(null);
|
const [editingBook, setEditingBook] = useState(null);
|
||||||
const [statusFilter, setStatusFilter] = useState(""); // пусто — все книги
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const [statusFilter, setStatusFilter] = useState("");
|
||||||
|
|
||||||
// Загрузка книг с сервера
|
// Загрузка книг с сервера
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -61,41 +61,43 @@ function App() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Фильтрация книг по статусу
|
// Фильтрация книг по поиску и статусу
|
||||||
const filteredBooks = statusFilter
|
const filteredBooks = books.filter(book =>
|
||||||
? books.filter(
|
book.title.toLowerCase().includes(searchQuery.toLowerCase()) &&
|
||||||
book =>
|
(statusFilter === "" ||
|
||||||
statuses.find(s => String(s.id) === String(book.statusId))?.name === statusFilter
|
statuses.find(s => String(s.id) === String(book.statusId))?.name === statusFilter)
|
||||||
)
|
);
|
||||||
: books;
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main className="container py-4">
|
<main className="container py-4">
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path="/"
|
path="/"
|
||||||
element={
|
element={
|
||||||
<Home
|
<Home
|
||||||
books={books}
|
books={filteredBooks}
|
||||||
authors={authors}
|
authors={authors}
|
||||||
statuses={statuses}
|
statuses={statuses}
|
||||||
editingBook={editingBook}
|
editingBook={editingBook}
|
||||||
onAdd={addBook}
|
onAdd={addBook}
|
||||||
onEdit={updateBook}
|
onEdit={updateBook}
|
||||||
onDelete={deleteBook}
|
onDelete={deleteBook}
|
||||||
onCancel={() => setEditingBook(null)}
|
onCancel={() => setEditingBook(null)}
|
||||||
setEditingBook={setEditingBook}
|
setEditingBook={setEditingBook}
|
||||||
/>
|
searchQuery={searchQuery}
|
||||||
}
|
setSearchQuery={setSearchQuery}
|
||||||
/>
|
statusFilter={statusFilter}
|
||||||
<Route path="/news" element={<News />} />
|
setStatusFilter={setStatusFilter}
|
||||||
<Route path="/manga/:id" element={<Manga />} />
|
/>
|
||||||
<Route path="/author/:id" element={<Author />} />
|
}
|
||||||
<Route path="/reading/:id" element={<Reading />} />
|
/>
|
||||||
<Route path="/account" element={<Account />} />
|
<Route path="/news" element={<News />} />
|
||||||
|
<Route path="/manga/:id" element={<Manga />} />
|
||||||
|
<Route path="/author/:id" element={<Author />} />
|
||||||
|
<Route path="/reading/:id" element={<Reading />} />
|
||||||
|
<Route path="/account" element={<Account />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
@@ -103,4 +105,4 @@ function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import BookForm from "./BookForm";
|
import BookForm from "./BookForm";
|
||||||
import BookList from "./BookList";
|
import BookList from "./BookList";
|
||||||
@@ -11,11 +12,34 @@ export default function Home({
|
|||||||
onEdit,
|
onEdit,
|
||||||
onDelete,
|
onDelete,
|
||||||
onCancel,
|
onCancel,
|
||||||
setEditingBook
|
setEditingBook,
|
||||||
|
searchQuery,
|
||||||
|
setSearchQuery,
|
||||||
|
statusFilter,
|
||||||
|
setStatusFilter
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className="mb-4">Книги</h1>
|
<h1 className="mb-4">Книги</h1>
|
||||||
|
<div className="mb-3" style={{ maxWidth: 350 }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control mb-2"
|
||||||
|
placeholder="Поиск по названию"
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={e => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
<select
|
||||||
|
className="form-select"
|
||||||
|
value={statusFilter}
|
||||||
|
onChange={e => setStatusFilter(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="">Все статусы</option>
|
||||||
|
{statuses.map(s => (
|
||||||
|
<option key={s.id} value={s.name}>{s.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<BookForm
|
<BookForm
|
||||||
authors={authors}
|
authors={authors}
|
||||||
statuses={statuses}
|
statuses={statuses}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export default function Navbar() {
|
|||||||
<Link className="navbar-brand" to="/">
|
<Link className="navbar-brand" to="/">
|
||||||
<img src="/img/manga.png" alt="ЛОГО" height="50" />
|
<img src="/img/manga.png" alt="ЛОГО" height="50" />
|
||||||
</Link>
|
</Link>
|
||||||
|
{/* Бургер-кнопка для мобилок */}
|
||||||
<button
|
<button
|
||||||
className="navbar-toggler"
|
className="navbar-toggler"
|
||||||
type="button"
|
type="button"
|
||||||
@@ -20,9 +21,18 @@ export default function Navbar() {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
<div className="collapse navbar-collapse ms-3" id="navbarNavDropdown">
|
||||||
|
<ul className="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||||
<Link to="/news" className="btn btn-outline-warning">Новости</Link>
|
<li className="nav-item me-2">
|
||||||
<Link to="/account" className="btn btn-outline-warning">Вход</Link>
|
<Link to="/news" className="btn btn-outline-warning">
|
||||||
|
Новости
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="nav-item">
|
||||||
|
<Link to="/account" className="btn btn-outline-warning">
|
||||||
|
Вход
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user