summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <rafizadanly@gmail.com>2022-11-16 11:54:22 +0700
committerRafi Zadanly <rafizadanly@gmail.com>2022-11-16 11:54:22 +0700
commit5786bd52bfc098d144dd77332c32edabd7cec251 (patch)
tree4f074878a72081021fa2bd41ed60b877c1c25dc1
parent194b7ba68bcb9502c5e3a4d8ffd5fbe39c7e18aa (diff)
Create pagination component
-rw-r--r--src/components/Pagination.js56
-rw-r--r--src/pages/api/shop/search.js1
-rw-r--r--src/pages/shop/search.js40
-rw-r--r--src/styles/globals.css49
4 files changed, 128 insertions, 18 deletions
diff --git a/src/components/Pagination.js b/src/components/Pagination.js
new file mode 100644
index 00000000..14f2ac0c
--- /dev/null
+++ b/src/components/Pagination.js
@@ -0,0 +1,56 @@
+import Link from "next/link"
+
+export default function Pagination({ pageCount, currentPage, url }) {
+ let firstPage = false;
+ let lastPage = false;
+ let dotsPrevPage = false;
+ let dotsNextPage = false;
+ return (
+ <div className="pagination">
+ {Array.from(Array(pageCount)).map((v, i) => {
+ let page = i + 1;
+ let rangePrevPage = currentPage - 2;
+ let rangeNextPage = currentPage + 2;
+ let PageComponent = <Link key={i} href={`${url}&page=${page}`} className={"pagination-item" + (page == currentPage ? " pagination-item--active " : "")}>{page}</Link>;
+ let DotsComponent = <div key={i} className="pagination-dots">...</div>;
+
+ if (pageCount == 7) {
+ return PageComponent;
+ }
+
+ if (currentPage == 1) rangeNextPage += 3;
+ if (currentPage == 2) rangeNextPage += 2;
+ if (currentPage == 3) rangeNextPage += 1;
+ if (currentPage == 4) rangePrevPage -= 1;
+ if (currentPage == pageCount) rangePrevPage -= 3;
+ if (currentPage == pageCount - 1) rangePrevPage -= 2;
+ if (currentPage == pageCount - 2) rangePrevPage -= 1;
+ if (currentPage == pageCount - 3) rangeNextPage += 1;
+
+ if (page > rangePrevPage && page < rangeNextPage) {
+ return PageComponent;
+ }
+
+ if (page == 1 && rangePrevPage >= 1 && !firstPage) {
+ firstPage = true;
+ return PageComponent;
+ }
+
+ if (page == pageCount && rangeNextPage <= pageCount && !lastPage) {
+ lastPage = true;
+ return PageComponent;
+ }
+
+ if (page > currentPage && (pageCount - currentPage) > 1 && !dotsNextPage) {
+ dotsNextPage = true;
+ return DotsComponent;
+ }
+
+ if (page < currentPage && (currentPage - 1) > 1 && !dotsPrevPage) {
+ dotsPrevPage = true;
+ return DotsComponent;
+ }
+ })}
+ </div>
+ )
+} \ No newline at end of file
diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js
index 3c3a1766..72db04fd 100644
--- a/src/pages/api/shop/search.js
+++ b/src/pages/api/shop/search.js
@@ -56,6 +56,7 @@ export default async function handler(req, res) {
'facet.field=category_name_str',
`start=${offset}`,
`rows=${limit}`,
+ 'sort=product_rating desc'
].join('&');
let result = await axios(process.env.SOLR_HOST + '/solr/products/select?' + parameter);
diff --git a/src/pages/shop/search.js b/src/pages/shop/search.js
index 6e6839be..92f1bf5a 100644
--- a/src/pages/shop/search.js
+++ b/src/pages/shop/search.js
@@ -1,19 +1,20 @@
import axios from "axios";
-import Link from "next/link";
-import { useEffect, useState } from "react";
import Header from "../../components/Header";
+import Pagination from "../../components/Pagination";
import ProductCard from "../../components/ProductCard";
export async function getServerSideProps(context) {
const { q, page = 1 } = context.query;
- let searchResults = await axios(`http://${context.req.headers.host}/api/shop/search?q=${q}&page=${page}`);
+ let searchResults = await axios(`${process.env.SELF_HOST}/api/shop/search?q=${q}&page=${page}`);
searchResults = searchResults.data;
- return { props: { searchResults, q } };
+ return { props: { searchResults, q, page } };
}
-export default function ShopSearch({ searchResults, q, page = 1 }) {
- const pageTotal = Math.ceil(searchResults.response.numFound / searchResults.responseHeader.params.rows);
-
+export default function ShopSearch({ searchResults, q, page }) {
+ const pageCount = Math.ceil(searchResults.response.numFound / searchResults.responseHeader.params.rows);
+ const productStart = searchResults.responseHeader.params.start;
+ const productRows = searchResults.responseHeader.params.rows;
+ const productFound = searchResults.response.numFound;
return (
<>
<Header title={`Jual ${q} - Indoteknik`} />
@@ -21,23 +22,26 @@ export default function ShopSearch({ searchResults, q, page = 1 }) {
<div className="p-4">
<h1 className="mb-1">Produk</h1>
<div className="text-xs mb-4">
- Menampilkan&nbsp;
- {searchResults.responseHeader.params.start + 1}-{searchResults.responseHeader.params.start + searchResults.responseHeader.params.rows}
- &nbsp;dari&nbsp;
- {searchResults.response.numFound}
- &nbsp;produk untuk pencarian {q}
+ {productFound > 0 ? (
+ <>
+ Menampilkan&nbsp;
+ {productStart + 1}-{
+ (productStart + productRows) > productFound ? productFound : productStart + productRows
+ }
+ &nbsp;dari&nbsp;
+ {searchResults.response.numFound}
+ &nbsp;produk untuk pencarian <span className="font-semibold">{q}</span>
+ </>
+ ) : 'Mungkin yang anda cari'}
</div>
<div className="grid grid-cols-2 gap-3">
{searchResults.response.products.map((product) => (
<ProductCard key={product.id} data={product} />
))}
</div>
- <div className="flex justify-center gap-x-1 mt-4">
- {[...Array(pageTotal)].map((v, i) => (
- <Link href={`/shop/search?q=${q}&page=${i+1}`} key={i} className={"p-1 px-2 rounded ease-linear duration-150 " + (page == (i + 1) ? "bg-yellow-900 text-white" : "bg-gray-100 hover:bg-gray-300 text-gray-900")}>
- {i + 1}
- </Link>
- ))}
+
+ <div className="mt-4">
+ <Pagination pageCount={pageCount} currentPage={parseInt(page)} url={`/shop/search?q=${q}`} />
</div>
</div>
</main>
diff --git a/src/styles/globals.css b/src/styles/globals.css
index d0080dda..6a5f86a8 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -266,4 +266,53 @@ html, body {
.swiper-pagination-bullet-active {
@apply !bg-yellow-900;
+}
+
+.pagination {
+ @apply
+ flex
+ justify-center
+ gap-x-1
+ ;
+}
+
+.pagination-item {
+ @apply
+ p-1
+ flex
+ justify-center
+ items-center
+ w-10
+ rounded
+ ease-linear
+ duration-150
+ border
+ border-gray-300
+ bg-gray-100
+ hover:bg-gray-300
+ text-gray-800
+ ;
+}
+
+.pagination-item--active {
+ @apply
+ border-yellow-900
+ bg-yellow-900
+ hover:bg-yellow-900
+ text-gray-900
+ ;
+}
+
+.pagination-dots {
+ @apply
+ p-1
+ flex
+ justify-center
+ items-end
+ w-10
+ rounded
+ ease-linear
+ bg-gray-100
+ text-sm
+ ;
} \ No newline at end of file