Сделали главное - получение всех книг и отображение книг по одной с главной страницы

This commit is contained in:
2025-09-20 01:41:45 +04:00
parent cc60f5808a
commit ba1ad50382
7 changed files with 160 additions and 24 deletions

View File

@@ -12,6 +12,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.12.2",
"bootstrap": "^5.3.8",
"react": "^19.1.1",
"react-dom": "^19.1.1",
@@ -4552,6 +4553,31 @@
"node": ">=4"
}
},
"node_modules/axios": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -12624,6 +12650,11 @@
"node": ">= 0.10"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",

View File

@@ -7,6 +7,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.12.2",
"bootstrap": "^5.3.8",
"react": "^19.1.1",
"react-dom": "^19.1.1",

View File

@@ -0,0 +1,33 @@
import axios from "axios";
const ONLINE_LIBRARY_URL = "http://localhost:8080/api/v1.0";
const api = axios.create({
baseURL: ONLINE_LIBRARY_URL,
timeout: 10000,
withCredentials: true,
headers: {
"Content-Type": "application/json",
},
});
export const bookAPI = {
getAll: (params = {}) => {
return api.get("/books", { params });
},
getBookById: (id) => {
return api.get(`/book/${id}`);
},
getBookByTitle: (title) => {
return api.get("/book", { params: { title } });
},
saveBook: (book) => {
return api.post("/book", book);
},
updateBook: (book) => {
return api.put("/book", book);
},
deelteBook: (id) => {
return api.delete("/book", { params: { id } });
},
};

View File

@@ -17,7 +17,7 @@ function App() {
<Route path="/search" element={<Search />}></Route>
<Route path="/choice" element={<Choice />}></Route>
<Route path="/lk" element={<Lk />}></Route>
<Route path="/infobook" element={<BookCardInfo />}></Route>
<Route path="/infobook/:id" element={<BookCardInfo />}></Route>
</Routes>
<Footer></Footer>
</BrowserRouter>

View File

@@ -1,25 +1,27 @@
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
import { Link } from "react-router-dom";
function BookCard({ title, linkOnImage }) {
function BookCard({book}) {
console.log("BookCard - " + book)
return (
<div className="col">
<div className="book-card p-3 h-100 text-center">
<img
src={`${process.env.PUBLIC_URL}${linkOnImage}`}
src={`${book.linkOnImage}`}
className="img-fluid rounded mb-3"
alt="Обложка книги"
/>
<p className="fs-5">
{title}
{book.title}
<br />
<a
href="/html/infobook.html"
<Link
to={`/infobook/${book.id}`}
className="text-decoration-none"
style={{ color: "var(--accent)" }}
>
Ссылка на переход
</a>
</Link>
</p>
</div>
</div>

View File

@@ -1,6 +1,42 @@
import { useLocation, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { bookAPI } from "../ApiRequest/ApiClient";
function BookCardInfo() {
const { id } = useParams();
const [book, setBook] = useState();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchBooks = async () => {
try {
setLoading(true);
const response = await bookAPI.getBookById(id);
console.log(response.data);
setBook(response.data);
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
fetchBooks();
}, [id]);
console.log(id);
const testObject = {
title: "Тестовая книга",
description: "Описание книги",
annotation: "Аннотация книги",
author: "Автор",
genre: "Жанр",
year: "1949",
};
if (loading) return <div> Загрузка</div>;
if (error) return <div> Ошибка: {error}</div>;
if(!book) return <div> Книга не найдена</div>;
return (
<body className="bg-dark text-light p-4">
{console.log(book.title)}
<div className="container">
<div
className="card bg-secondary border-0 shadow-lg mb-4"
@@ -8,13 +44,15 @@ function BookCardInfo() {
>
<div className="card-body">
<h1 className="text-center mb-4" style={{ color: "#00adb5" }}>
Описание книги
{book.title}
</h1>
<h2 className="fs-1 mb-3">Джордж Оруэлл "1984"</h2>
<h2 className="fs-1 mb-3">
{book.description || testObject.description}
</h2>
<div className="text-center mb-4">
<img
src="/res/1984.jpg"
src={book.linkOnImage}
alt="Обложка книги 1984"
className="img-fluid rounded"
style={{ maxWidth: "300px" }}
@@ -23,11 +61,11 @@ function BookCardInfo() {
<div className="mb-4 p-3 --bg-medium rounded">
<p className="mb-0">
<strong>Автор:</strong> Джордж Оруэлл
<strong>Автор:</strong> {book.author}
<br />
<strong>Жанр:</strong> Антиутопия
<strong>Жанр:</strong> {book.genre}
<br />
<strong>Год издания:</strong> 1949
<strong>Год издания:</strong> {book.year || testObject.year}
</p>
</div>
@@ -35,16 +73,7 @@ function BookCardInfo() {
<h5 className="text-accent mb-3" style={{ color: "#00adb5" }}>
Аннотация:
</h5>
<p className="lh-base">
Роман "1984" Джорджа Оруэлла это классика антиутопической
литературы. Действие происходит в тоталитарном обществе, где
правительство контролирует каждую мысль и действие граждан.
Главный герой, Уинстон Смит, работает в Министерстве правды, где
он подделывает исторические документы, чтобы они соответствовали
текущей партийной линии. Однако Уинстон начинает сомневаться в
системе и искать способы сопротивления. Роман исследует темы
свободы, правды и власти, оставаясь актуальным и по сей день.
</p>
<p className="lh-base">{book.annotation}</p>
</div>
<div className="text-center">

View File

@@ -2,12 +2,52 @@ import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
import "../style.css";
import BookCard from "../BookCard/BookCard";
import { useEffect, useState } from "react";
import { bookAPI } from "../ApiRequest/ApiClient";
function Main() {
const [bookData, setBookData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchBooks = async () => {
try {
setIsLoading(true);
const response = await bookAPI.getAll();
setBookData(response.data);
} catch (error) {
setError(error.message);
} finally {
setIsLoading(false);
}
};
fetchBooks();
}, []);
if (isLoading) return <div> Загрузка</div>;
if (error) return <div> Ошибка: {error}</div>;
return (
<div className="container">
<div className="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
<BookCard title={"Джордж укыавяыав"} linkOnImage={"../resources/1984.jpg"}></BookCard>
{console.log(bookData)}
{bookData.map((book) => (
<BookCard book={book}></BookCard>
))}
{/* <BookCard
title={"Джордж укыавяыав"}
linkOnImage={"../resources/1984.jpg"}
></BookCard>
<BookCard
title={"Джордж укыавяыав"}
linkOnImage={"../resources/1984.jpg"}
></BookCard>
<BookCard
title={"Джордж укыавяыав"}
linkOnImage={"../resources/1984.jpg"}
></BookCard>
<BookCard
title={"Джордж укыавяыав"}
linkOnImage={"../resources/1984.jpg"}
></BookCard> */}
</div>
</div>
);