добавил поиск по названию и вернул филтрацию

This commit is contained in:
2025-05-25 13:40:14 +04:00
parent 616e8e76c9
commit e527a79d0c
4 changed files with 80 additions and 36 deletions

File diff suppressed because one or more lines are too long

View File

@@ -15,8 +15,8 @@ function App() {
const [authors] = useState(data.authors);
const [statuses] = useState(data.statuses);
const [editingBook, setEditingBook] = useState(null);
const [statusFilter, setStatusFilter] = useState(""); // пусто — все книги
const [searchQuery, setSearchQuery] = useState("");
const [statusFilter, setStatusFilter] = useState("");
// Загрузка книг с сервера
useEffect(() => {
@@ -61,41 +61,43 @@ function App() {
});
};
// Фильтрация книг по статусу
const filteredBooks = statusFilter
? books.filter(
book =>
statuses.find(s => String(s.id) === String(book.statusId))?.name === statusFilter
)
: books;
// Фильтрация книг по поиску и статусу
const filteredBooks = books.filter(book =>
book.title.toLowerCase().includes(searchQuery.toLowerCase()) &&
(statusFilter === "" ||
statuses.find(s => String(s.id) === String(book.statusId))?.name === statusFilter)
);
return (
<>
<Navbar />
<main className="container py-4">
<Routes>
<Route
path="/"
element={
<Home
books={books}
authors={authors}
statuses={statuses}
editingBook={editingBook}
onAdd={addBook}
onEdit={updateBook}
onDelete={deleteBook}
onCancel={() => setEditingBook(null)}
setEditingBook={setEditingBook}
/>
}
/>
<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 />} />
<Route
path="/"
element={
<Home
books={filteredBooks}
authors={authors}
statuses={statuses}
editingBook={editingBook}
onAdd={addBook}
onEdit={updateBook}
onDelete={deleteBook}
onCancel={() => setEditingBook(null)}
setEditingBook={setEditingBook}
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
statusFilter={statusFilter}
setStatusFilter={setStatusFilter}
/>
}
/>
<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>
</main>
<Footer />
@@ -103,4 +105,4 @@ function App() {
);
}
export default App;
export default App;

View File

@@ -1,3 +1,4 @@
import React from "react";
import BookForm from "./BookForm";
import BookList from "./BookList";
@@ -11,11 +12,34 @@ export default function Home({
onEdit,
onDelete,
onCancel,
setEditingBook
setEditingBook,
searchQuery,
setSearchQuery,
statusFilter,
setStatusFilter
}) {
return (
<>
<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
authors={authors}
statuses={statuses}

View File

@@ -7,6 +7,7 @@ export default function Navbar() {
<Link className="navbar-brand" to="/">
<img src="/img/manga.png" alt="ЛОГО" height="50" />
</Link>
{/* Бургер-кнопка для мобилок */}
<button
className="navbar-toggler"
type="button"
@@ -20,9 +21,18 @@ export default function Navbar() {
</button>
<div className="collapse navbar-collapse ms-3" id="navbarNavDropdown">
<Link to="/news" className="btn btn-outline-warning">Новости</Link>
<Link to="/account" className="btn btn-outline-warning">Вход</Link>
<ul className="navbar-nav ms-auto mb-2 mb-lg-0">
<li className="nav-item me-2">
<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>
</nav>
);