Skip to content

Commit

Permalink
refactor:search system
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammadhasanii committed Nov 11, 2024
1 parent a4a7258 commit 1adc443
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 278 deletions.
316 changes: 128 additions & 188 deletions components/Home/Main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,222 +5,162 @@ import { AiOutlineSearch } from "react-icons/ai";
import Select from "../common/Select";
import { AxiosInstance } from "../../utils/http";
import SingleRowBook from "./SingleRowBook";

import LazyBookComponent from "./LazyBook";

export default function MainComponent() {
const router = useRouter(); // new instance for router
const { bookName, libraryId, pageId, categoryId } = router.query; //Load Params as Query

//CURRENT STATE

const [currentBookName, setCurrentBookName] = useState(
bookName ? bookName : ""
);

const [currentLibraryId, setCurrentLibraryId] = useState(
libraryId ? parseInt(libraryId) : null
);

const [currentCategoryId, setCurrentCategoryId] = useState(
categoryId != undefined ? parseInt(categoryId) : null
);

const [currenPageId, setCurrentPageId] = useState(
pageId != undefined ? parseInt(pageId) : 1
);

const router = useRouter();
const { bookName, libraryId, pageId, categoryId } = router.query;

// State variables
const [currentBookName, setCurrentBookName] = useState(bookName || "");
const [currentLibraryId, setCurrentLibraryId] = useState(libraryId ? parseInt(libraryId) : null);
const [currentCategoryId, setCurrentCategoryId] = useState(categoryId ? parseInt(categoryId) : null);
const [currenPageId, setCurrentPageId] = useState(pageId ? parseInt(pageId) : 1);
const [currenLoading, setCurrentLoading] = useState(true);

const [defaultValueLibrary, setDefaultValueLibrary] = useState(libraryId);

const [books, setBooks] = useState([]);
const [totalResults, setTotalResults] = useState(0); // Total number of results from API

//LOCAL STATE

const [libraries, SetLibraries] = useState([]);

// Dropdown options
const [libraries, setLibraries] = useState([]);
const [categories, setCategories] = useState([]);

//For GetAll Libraries
// Load libraries on component mount
useEffect(() => {
AxiosInstance.get("/home/libraries").then((res) => {
SetLibraries(res.data);
setLibraries(res.data);
});
}, []);

//For GetAll Categories For LibraryId
useEffect(async () => {
await AxiosInstance.get(`/home/categories/${currentLibraryId}`)
.then((res) => {
setCategories(res.data);
})
.catch((e) => console.log(e));
// Load categories when libraryId changes
useEffect(() => {
if (currentLibraryId) {
AxiosInstance.get(`/home/categories/${currentLibraryId}`)
.then((res) => setCategories(res.data))
.catch((e) => console.log(e));
}
}, [currentLibraryId]);

//LOGIC SEARCH AND CHANGE ROUTER
const bookSearch = () => {
// Fetch books whenever query parameters in the URL change (including pageId)
useEffect(() => {
const fetchBooks = async () => {
setCurrentLoading(true);
const result = await last_search(currentBookName, currentLibraryId, currenPageId, currentCategoryId);
setBooks(result); // Assuming the result contains a 'books' array
setTotalResults(result.totalResults); // Assuming the result contains total results info
setCurrentLoading(false);
};

fetchBooks();
}, [currenPageId, currentBookName, currentLibraryId, currentCategoryId]); // Trigger fetch when any query changes

// Update query parameters in the URL
const updateQueryParams = () => {
const params = new URLSearchParams();
const newPageNumber = 1;
setCurrentPageId(newPageNumber);
currentBookName && params.append("bookName", currentBookName);
currentLibraryId && params.append("libraryId", currentLibraryId);
params.append("pageId", newPageNumber);
currentCategoryId && params.append("categoryId", currentCategoryId);

const queryString = params.toString();

router.push(`?${queryString}`);
if (currentBookName) params.append("bookName", currentBookName);
if (currentLibraryId) params.append("libraryId", currentLibraryId);
if (currentCategoryId) params.append("categoryId", currentCategoryId);
params.append("pageId", currenPageId); // Keep current pageId in URL
router.push(`?${params.toString()}`);
};

const bookSearchLoadingPrevius = () => {
const newPageNumber = currenPageId - 1;
setCurrentPageId(newPageNumber);
const params = new URLSearchParams();
currentBookName && params.append("bookName", currentBookName);
currentLibraryId && params.append("libraryId", currentLibraryId);
currenPageId && params.append("pageId", newPageNumber);
currentCategoryId && params.append("categoryId", currentCategoryId);

const queryString = params.toString();

router.push(`?${queryString}`);
// Handle changes in form inputs and update query parameters
const handleSearchChange = () => {
updateQueryParams();
};

const bookSearchLoading = () => {
const newPageNumber = currenPageId + 1;
setCurrentPageId(newPageNumber);
const params = new URLSearchParams();
currentBookName && params.append("bookName", currentBookName);
currentLibraryId && params.append("libraryId", currentLibraryId);
currenPageId && params.append("pageId", newPageNumber);
currentCategoryId && params.append("categoryId", currentCategoryId);

const queryString = params.toString();

router.push(`?${queryString}`);
// Handle page change
const handlePageChange = (newPage) => {
const totalPages = Math.ceil(totalResults / 10); // Assuming 10 books per page
if (newPage < 1 || newPage > totalPages) return;
setCurrentPageId(newPage);
updateQueryParams();
};

//END QUERY STRING RENDER

useEffect(async () => {
setBooks([]);
setCurrentLoading(true);
await new Promise((resolve) => setTimeout(resolve, 500));

const { bookName, libraryId, pageId, categoryId } = router.query;
console.log(router.query);
setCurrentCategoryId(categoryId);
setCurrentBookName(bookName);
setCurrentLibraryId(libraryId);
setCurrentPageId(parseInt(pageId));
const result = await last_search(bookName, libraryId, pageId, categoryId);
setCurrentLoading(false);
setBooks(result);
}, [router.query]);

return (
<>
<div className="row">



<form
className="md:mb-8 lg:w-2/3 mx-auto flex flex-col md:flex-row md:items-center mb-4 lg:mt-8 mt-1 lg:px-0 sm:px-4 "
onSubmit={(e) => e.preventDefault()}
>
<Select
keyName="libraryName"
items={libraries}
label={"همه کتابخانه ها"}
defaultValue={currentLibraryId}
onChange={(v) => setCurrentLibraryId(Number(v))}
ClassName={
"md:w-1/4 text-gray-700 rounded-lg bg-gray-50 border border-gray-300 focus:ring-1 focus:outline-none focus:ring-green-500 focus:border-green-500 "
}
/>
<Select
defaultValue={currentCategoryId}
keyName="categoryName"
items={categories}
onChange={(v, keyName) => {
setCurrentCategoryId(Number(v));
}}
label={"انتخاب همه دسته ها"}
ClassName={
"md:w-1/4 lg:mx-4 mx-0 mt-1 text-gray-700 rounded-lg bg-gray-50 border focus:ring-1 focus:outline-none border-gray-300 focus:ring-green-500 focus:border-green-500 "
}
<div className="row">
<form
className="md:mb-8 lg:w-2/3 mx-auto flex flex-col md:flex-row md:items-center mb-4 lg:mt-8 mt-1 lg:px-0 sm:px-4"
onSubmit={(e) => {
e.preventDefault();
updateQueryParams(); // When form is submitted, just update the query
}}
>
<Select
keyName="libraryName"
items={libraries}
label={"همه کتابخانه ها"}
defaultValue={currentLibraryId}
onChange={(v) => { setCurrentLibraryId(Number(v)); handleSearchChange(); }}
ClassName="md:w-1/4 text-gray-700 rounded-lg bg-gray-50 border border-gray-300 focus:ring-1 focus:outline-none focus:ring-green-500 focus:border-green-500"
/>
<Select
defaultValue={currentCategoryId}
keyName="categoryName"
items={categories}
onChange={(v) => { setCurrentCategoryId(Number(v)); handleSearchChange(); }}
label={"انتخاب همه دسته ها"}
ClassName="md:w-1/4 lg:mx-4 mx-0 mt-1 text-gray-700 rounded-lg bg-gray-50 border focus:ring-1 focus:outline-none border-gray-300 focus:ring-green-500 focus:border-green-500"
/>

<div className="relative mt-1 md:w-3/4 mb-4 md:mb-0">
<input
autoComplete="off"
type="search"
id="default-search"
className="py-5 pr-5 pl-10 w-full md:text-base outline-none focus:ring-1 text-sm rounded-lg text-gray-900 bg-gray-50 border border-gray-300 focus:ring-green-500 focus:border-green-500"
placeholder={"جست و جو در بین 40 هزار جلد کتاب"}
onChange={(e) => { setCurrentBookName(e.target.value); handleSearchChange(); }}
value={currentBookName}
/>

<div className="relative mt-1 md:w-3/4 mb-4 md:mb-0 ">
<input
autoComplete="off"
type="search"
id="default-search"
className=" py-5 pr-5 pl-10 w-full md:text-base outline-none focus:ring-1 text-sm rounded-lg text-gray-900 bg-gray-50 border border-gray-300 focus:ring-green-500 focus:border-green-500"
placeholder={"جست و جو در بین 40 هزار جلد کتاب"}
onChange={(e) => setCurrentBookName(e.target.value)}
value={currentBookName}
<button
type="submit"
className="text-white left-2.5 bottom-3 top-3 absolute bg-green-600 font-medium rounded-lg text-sm px-4 py-2"
>
<AiOutlineSearch size={20} className="h-auto" />
<span className="sr-only">Search</span>
</button>
</div>
</form>

{currenLoading ? (
<div className="flex items-center justify-center">
<LazyBookComponent />
</div>
) : (
<section className="grid md:grid-cols-2 lg:w-2/3 lg:mx-auto bg-white shadow-lg rounded-md p-2 lg:grid-cols-4 2xl:grid-cols-5 sm:grid-cols-3 grid-cols-3">
{books?.map((value) => (
<SingleRowBook
key={value.id}
imageSource={value.imageSource}
bookId={value.id}
categoryName={value.subCategory.category.categoryName}
bookName={value.bookName}
publisherName={value.publisherName}
/>
))}
</section>
)}

{!currenLoading && totalResults > 10 && (
<div className="flex justify-center mx-auto my-16">
{currenPageId > 1 && (
<button
onClick={bookSearch}
type="submit"
className=" text-white left-2.5 bottom-3 top-3 absolute bg-green-600 font-medium rounded-lg text-sm px-4 py-2 "
onClick={() => handlePageChange(currenPageId - 1)}
className="inline-flex justify-center items-center gap-x-2 text-center bg-white border hover:border-gray-300 text-sm text-green-600 hover:text-green-700 font-medium hover:shadow-sm rounded-full focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition py-3 px-4"
>
<div>
<AiOutlineSearch size={20} className="h-auto" />
<span className="sr-only">Search</span>
</div>
قبلی
</button>
)}
{currenPageId < Math.ceil(totalResults / 10) && (
<button
onClick={() => handlePageChange(currenPageId + 1)}
className="inline-flex justify-center items-center gap-x-2 text-center bg-white border hover:border-gray-300 text-sm text-green-600 hover:text-green-700 font-medium hover:shadow-sm rounded-full focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition py-3 px-4"
>
بعدی
</button>
</div>
</form>

{currenLoading && (
<div className="flex items-center justify-center ">
<LazyBookComponent />
</div>
)}

{!currenLoading && (
<section className="grid md:grid-cols-2 lg:w-2/3 lg:mx-auto bg-white shadow-lg rounded-md p-2 lg:grid-cols-4 2xl:grid-cols-5 sm:grid-cols-3 grid-cols-3">
{books.map((value, index) => {
const modifiedImageSource = value.imageSource.replace('https://bookito-data-storage.storage.iran.liara.space/images/', 'https://boookito.storage.ir/');
return (
<SingleRowBook
key={value.id}
imageSource={'/images/nophoto.png'}
bookId={value.id}
categoryName={value.subCategory.category.categoryName}
bookName={value.bookName}
publisherName={value.publisherName}
/>
);
})}
</section>
)}
<>
{!currenLoading && (
<div className="flex justify-center mx-auto my-16">
{/* Previous Button */}
{currenPageId > 1 && (
<button
onClick={bookSearchLoadingPrevius}
className="inline-flex justify-center items-center gap-x-2 text-center bg-white border hover:border-gray-300 text-sm text-green-600 hover:text-green-700 font-medium hover:shadow-sm rounded-full focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition py-3 px-4 "
>
قبلی
</button>
)}

<button
onClick={bookSearchLoading}
className="inline-flex justify-center items-center gap-x-2 text-center bg-white border hover:border-gray-300 text-sm text-green-600 hover:text-green-700 font-medium hover:shadow-sm rounded-full focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition py-3 px-4 "
>
بعدی
</button>
</div>
)}
</>
</div>
</>
</div>
)}
</div>
);
}
24 changes: 8 additions & 16 deletions components/Home/PageBook.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,22 @@ export default function PageBook({ id }) {
<div className="w-full lg:w-1/2 px-4 mb-16 lg:mb-0">
<div className="flex -mx-4 flex-wrap items-center justify-between lg:justify-start lg:items-start xl:items-center">
<div className="w-full sm:w-9/12 px-4 ">
<Image
src={allbooks.imageSource}
<img
src={
allbooks.imageSource ==
"https://bookito-object-storage.storage.iran.liara.space/nophoto.png"
? "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRSWSxsVpAmqb_T7CLGolJ193Bw9xh7X7r0yQ&s"
: allbooks.imageSource
}
alt="Just a flower"
width={1000}
height={950}
priority
placeholder="blur"
blurDataURL="YOUR_GENERATED_BLURHASH_STRING"
quality={1}
layout="responsive"
objectFit="contain"
className="rounded-md"
className="rounded-md h-full"
/>
{/* <img
className="mb-5 rounded-lg "
src={allbooks.imageSource}
alt=""
/> */}
</div>
</div>
</div>
<div className="w-full lg:w-1/2 px-4">
<div className="max-w-md mb-6">

<h2 className="mt-6 mb-4 font-bold text-gray-600 text-2xl md:text-7xl lg:text-2xl font-heading ">
{allbooks.bookName}
</h2>
Expand Down
Loading

0 comments on commit 1adc443

Please sign in to comment.