diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/Pagination.js | 56 | ||||
| -rw-r--r-- | src/pages/api/shop/search.js | 1 | ||||
| -rw-r--r-- | src/pages/shop/search.js | 40 | ||||
| -rw-r--r-- | src/styles/globals.css | 49 |
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 - {searchResults.responseHeader.params.start + 1}-{searchResults.responseHeader.params.start + searchResults.responseHeader.params.rows} - dari - {searchResults.response.numFound} - produk untuk pencarian {q} + {productFound > 0 ? ( + <> + Menampilkan + {productStart + 1}-{ + (productStart + productRows) > productFound ? productFound : productStart + productRows + } + dari + {searchResults.response.numFound} + 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 |
