From be4dac443438a6eaf63f34d6a93cdc00c469bbec Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 23 Nov 2022 10:57:58 +0700 Subject: Filter by price from and price to, optimize code component filter, fix style brand --- src/components/Filter.js | 83 ++++++++++++++++++++++++++++++++++++-------- src/components/Header.js | 2 +- src/pages/api/shop/search.js | 6 ++-- src/pages/shop/brands.js | 15 ++++---- src/pages/shop/search.js | 80 ++++++++++++++++++++---------------------- 5 files changed, 119 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/components/Filter.js b/src/components/Filter.js index cb8fd626..a07beff3 100644 --- a/src/components/Filter.js +++ b/src/components/Filter.js @@ -1,28 +1,78 @@ +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; import CloseIcon from "../icons/close.svg"; const Filter = ({ - selectedBrand, - onChangeBrand, - selectedCategory, - onChangeCategory, - brands, - categories, - isActiveFilter, + isActive, closeFilter, - onSubmit + defaultRoute, + defaultPriceFrom, + defaultPriceTo, + defaultCategory, + defaultBrand, + searchResults }) => { + const router = useRouter(); + + const [priceFrom, setPriceFrom] = useState(defaultPriceFrom); + const [priceTo, setPriceTo] = useState(defaultPriceTo); + const [selectedCategory, setSelectedCategory] = useState(defaultCategory); + const [selectedBrand, setSelectedBrand] = useState(defaultBrand); + const [categories, setCategories] = useState([]); + const [brands, setBrands] = useState([]); + + const filterRoute = () => { + let filterRoute = defaultRoute; + if (selectedBrand) filterRoute += `&brand=${selectedBrand}`; + if (selectedCategory) filterRoute += `&category=${selectedCategory}`; + if (priceFrom > 0) filterRoute += `&price_from=${priceFrom}`; + if (priceTo > 0) filterRoute += `&price_to=${priceTo}`; + return filterRoute; + } + + useEffect(() => { + const filterCategory = searchResults.facet_counts.facet_fields.category_name_str.filter((category, index) => { + if (index % 2 == 0) { + const productCountInCategory = searchResults.facet_counts.facet_fields.category_name_str[index + 1]; + if (productCountInCategory > 0) return category; + } + }); + setCategories(filterCategory); + + const filterBrand = searchResults.facet_counts.facet_fields.brand_str.filter((brand, index) => { + if (index % 2 == 0) { + const productCountInBrand = searchResults.facet_counts.facet_fields.brand_str[index + 1]; + if (productCountInBrand > 0) return brand; + } + }); + setBrands(filterBrand); + }, [searchResults]); + + const submit = (e) => { + e.preventDefault(); + closeFilter(); + router.push(filterRoute(), undefined, { scroll: false }); + } + + const reset = () => { + setSelectedBrand(''); + setSelectedCategory(''); + setPriceFrom(0); + setPriceTo(0); + } + return ( -
+

Filter Produk

-
+
- setSelectedCategory(e.target.value)}> {categories?.map((category, index) => ( @@ -31,7 +81,7 @@ const Filter = ({
- setSelectedBrand(e.target.value)}> {brands?.map((brand, index) => ( @@ -41,14 +91,19 @@ const Filter = ({
- + setPriceFrom(e.target.value)}/> - - + setPriceTo(e.target.value)}/>
+ {selectedBrand || selectedCategory || priceFrom > 0 || priceTo > 0 ? ( + + ) : ''}
) diff --git a/src/components/Header.js b/src/components/Header.js index f5eb22f4..2a33df63 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -108,7 +108,7 @@ export default function Header({ title }) { name="q" onChange={(e) => setSearchQuery(e.target.value)} value={searchQuery} - className="form-input rounded-r-none border-r-0" + className="form-input rounded-r-none border-r-0 focus:ring-0" placeholder="Ketikan nama, merek, part number" /> ))} @@ -59,7 +60,7 @@ export default function Brands({ initialManufactures }) { dataLength={manufactures.length} next={getMoreManufactures} hasMore={hasMoreManufacture} - className="grid grid-cols-3 gap-4 mt-6 !overflow-x-hidden" + className="grid grid-cols-4 gap-4 mt-6 !overflow-x-hidden" loader={
diff --git a/src/pages/shop/search.js b/src/pages/shop/search.js index f41adf3e..29c5b106 100644 --- a/src/pages/shop/search.js +++ b/src/pages/shop/search.js @@ -4,18 +4,33 @@ import Layout from "../../components/Layout"; import Pagination from "../../components/Pagination"; import ProductCard from "../../components/ProductCard"; import FilterIcon from "../../icons/filter.svg"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import Filter from "../../components/Filter"; import { useRouter } from "next/router"; export async function getServerSideProps(context) { - const { q, page = 1, brand = '', category = '' } = context.query; - let searchResults = await axios(`${process.env.SELF_HOST}/api/shop/search?q=${q}&page=${page}&brand=${brand}&category=${category}`); + const { + q, + page = 1, + brand = '', + category = '', + price_from = '0', + price_to = '0' + } = context.query; + + let urlParameter = [ + `page=${page}`, + `brand=${brand}`, + `category=${category}`, + `price_from=${price_from}`, + `price_to=${price_to}`, + ].join('&'); + let searchResults = await axios(`${process.env.SELF_HOST}/api/shop/search?q=${q}&${urlParameter}`); searchResults = searchResults.data; - return { props: { searchResults, q, page, brand, category } }; + return { props: { searchResults, q, page, brand, category, price_from, price_to } }; } -export default function ShopSearch({ searchResults, q, page, brand, category }) { +export default function ShopSearch({ searchResults, q, page, brand, category, price_from, price_to }) { const router = useRouter(); const pageCount = Math.ceil(searchResults.response.numFound / searchResults.responseHeader.params.rows); @@ -23,51 +38,30 @@ export default function ShopSearch({ searchResults, q, page, brand, category }) const productRows = searchResults.responseHeader.params.rows; const productFound = searchResults.response.numFound; + // Variable for props state const [activeFilter, setActiveFilter] = useState(false); - const [selectedCategory, setSelectedCategory] = useState(category); - const [selectedBrand, setSelectedBrand] = useState(brand); - const [categories, setCategories] = useState([]); - const [brands, setBrands] = useState([]); - const filterSubmit = (e) => { - e.preventDefault(); - setActiveFilter(false); - let filterRoute = `/shop/search?q=${q}`; - if (selectedBrand) filterRoute += `&brand=${selectedBrand}`; - if (selectedCategory) filterRoute += `&category=${selectedCategory}`; - router.push(filterRoute, undefined, { scroll: false }); + const route = () => { + let route = `/shop/search?q=${q}`; + if (brand) route += `&brand=${brand}`; + if (category) route += `&category=${category}`; + if (price_from > 0) route += `&price_from=${price_from}`; + if (price_to > 0) route += `&price_to=${price_to}`; + return route; } - useEffect(() => { - const filterCategory = searchResults.facet_counts.facet_fields.category_name_str.filter((category, index) => { - if (index % 2 == 0) { - const productCountInCategory = searchResults.facet_counts.facet_fields.category_name_str[index + 1]; - if (productCountInCategory > 0) return category; - } - }); - setCategories(filterCategory); - - const filterBrand = searchResults.facet_counts.facet_fields.brand_str.filter((brand, index) => { - if (index % 2 == 0) { - const productCountInBrand = searchResults.facet_counts.facet_fields.brand_str[index + 1]; - if (productCountInBrand > 0) return brand; - } - }); - setBrands(filterBrand); - }, [searchResults]); return ( <>
setSelectedBrand(e.target.value)} - selectedCategory={selectedCategory} - onChangeCategory={(e) => setSelectedCategory(e.target.value)} - brands={brands} - categories={categories} - isActiveFilter={activeFilter} - closeFilter={() => setActiveFilter(false)} - onSubmit={filterSubmit} + defaultRoute={`/shop/search?q=${q}`} + isActive={activeFilter} + closeFilter={() => setActiveFilter(false)} + defaultPriceFrom={price_from} + defaultPriceTo={price_to} + defaultBrand={brand} + defaultCategory={category} + searchResults={searchResults} />
@@ -99,7 +93,7 @@ export default function ShopSearch({ searchResults, q, page, brand, category })
- +
-- cgit v1.2.3