From 8876e48c35f41b77e61ba90bd95ab4c993d67e9e Mon Sep 17 00:00:00 2001 From: "HATEC\\SPVDEV001" Date: Mon, 27 Mar 2023 11:27:48 +0700 Subject: page search & page brand --- package.json | 2 + src/lib/brand/components/Brand.jsx | 128 ++++++---- src/lib/product/api/productSearchApi.js | 2 +- .../product/components/ProductFilterDesktop.jsx | 147 ++++++++++++ src/lib/product/components/ProductSearch.jsx | 258 ++++++++++++++++----- tailwind.config.js | 12 +- 6 files changed, 447 insertions(+), 102 deletions(-) create mode 100644 src/lib/product/components/ProductFilterDesktop.jsx diff --git a/package.json b/package.json index 3f9ef1a7..0d51e896 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "axios": "^1.1.3", "camelcase-object-deep": "^1.1.7", "cookies-next": "^2.1.1", + "flowbite": "^1.6.4", + "flowbite-react": "^0.4.2", "framer-motion": "^7.6.7", "lodash-contrib": "^4.1200.1", "midtrans-client": "^1.3.1", diff --git a/src/lib/brand/components/Brand.jsx b/src/lib/brand/components/Brand.jsx index c338c4c4..db4e81da 100644 --- a/src/lib/brand/components/Brand.jsx +++ b/src/lib/brand/components/Brand.jsx @@ -8,6 +8,8 @@ import 'swiper/css/pagination' import 'swiper/css/autoplay' import Divider from '@/core/components/elements/Divider/Divider' import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' +import MobileView from '@/core/components/views/MobileView' +import DesktopView from '@/core/components/views/DesktopView' const swiperBanner = { pagination: { dynamicBullets: true }, @@ -23,46 +25,94 @@ const Brand = ({ id }) => { return ( <> -
- {brand.isLoading && } - {brand.data && ( - <> - - {brand.data?.banners?.map((banner, index) => ( - - {`Brand - - ))} - -
-
Produk dari brand:
- {brand?.data?.logo && ( - {brand?.data?.name} - )} - {!brand?.data?.logo && ( -
- {brand?.data?.name} + + <> +
+ {brand.isLoading && } + {brand.data && ( + <> + + {brand.data?.banners?.map((banner, index) => ( + + {`Brand + + ))} + +
+
Produk dari brand:
+ {brand?.data?.logo && ( + {brand?.data?.name} + )} + {!brand?.data?.logo && ( +
+ {brand?.data?.name} +
+ )}
- )} -
- - )} -
- + + )} +
+ + + + +
+
+ {brand.isLoading && } + {brand.data && ( + <> + + {brand.data?.banners?.map((banner, index) => ( + + {`Brand + + ))} + +
+
Produk dari brand:
+ {brand?.data?.logo && ( + {brand?.data?.name} + )} + {!brand?.data?.logo && ( +
+ {brand?.data?.name} +
+ )} +
+ + )} +
+ +
+
) } diff --git a/src/lib/product/api/productSearchApi.js b/src/lib/product/api/productSearchApi.js index e7ad49a6..f626e8cc 100644 --- a/src/lib/product/api/productSearchApi.js +++ b/src/lib/product/api/productSearchApi.js @@ -2,7 +2,7 @@ import _ from 'lodash-contrib' import axios from 'axios' const productSearchApi = async ({ query }) => { - const dataProductSearch = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}`) + const dataProductSearch = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}&operation=OR`) return dataProductSearch.data } diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx new file mode 100644 index 00000000..276a7cc9 --- /dev/null +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -0,0 +1,147 @@ +import BottomPopup from '@/core/components/elements/Popup/BottomPopup' +import { useRouter } from 'next/router' +import { useState } from 'react' +import _ from 'lodash' +import { toQuery } from 'lodash-contrib' +import { Accordion, Badge, Checkbox, Label, TextInput } from 'flowbite-react' + +const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => { + const router = useRouter() + const { query } = router + const [order, setOrder] = useState(query?.orderBy) + const [brandValues, setBrand] = useState(query?.brand?.split(',') || []) + const [categoryValues, setCategory] = useState(query?.category?.split(',') || []) + const [priceFrom, setPriceFrom] = useState(query?.priceFrom) + const [priceTo, setPriceTo] = useState(query?.priceTo) + + const handleCategorysChange = (event) => { + const value = event.target.value + const isChecked = event.target.checked + if (isChecked) { + setCategory([...categoryValues, value]) + } else { + setCategory(categoryValues.filter((val) => val !== value)) + } + } + const handleBrandsChange = (event) => { + const value = event.target.value + const isChecked = event.target.checked + if (isChecked) { + setBrand([...brandValues, value]) + } else { + setBrand(brandValues.filter((val) => val !== value)) + } + } + + console.log('branddddd', defaultBrand) + + const handleSubmit = () => { + let params = { + q: router.query.q, + orderBy: order, + brand: brandValues.join(','), + category: categoryValues.join(','), + priceFrom, + priceTo + } + params = _.pickBy(params, _.identity) + params = toQuery(params) + router.push(`${prefixUrl}?${params}`) + } + + return ( + <> + + + Kategori + +
+ {categories.map((category, index) => ( +
+ + + {/*
250
*/} +
+ ))} +
+
+
+ + {!defaultBrand && ( + <> + Brand + +
+ {brands.map((brand, index) => ( +
+ + + {/*
250
*/} +
+ ))} +
+
+ + )} +
+ + Harga + +
+ setPriceFrom(e.target.value)} + /> +
+
+ setPriceTo(e.target.value)} + /> +
+
+
+
+
+ +
+ + ) +} + +export default ProductFilterDesktop diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 52bd5119..3078eac5 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -7,8 +7,15 @@ import _ from 'lodash' import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton' import ProductFilter from './ProductFilter' import useActive from '@/core/hooks/useActive' +import MobileView from '@/core/components/views/MobileView' +import DesktopView from '@/core/components/views/DesktopView' +import NextImage from 'next/image' +import { ChevronDownIcon } from '@heroicons/react/24/outline' +import ProductFilterDesktop from './ProductFilterDesktop' +import { useRouter } from 'next/router' const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { + const router = useRouter() const { page = 1 } = query if (defaultBrand) query.brand = defaultBrand.toLowerCase() const { productSearch } = useProductSearch({ query }) @@ -35,6 +42,29 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { } ) + const [open, setOpen] = useState(1) + const [order, setOrder] = useState(query?.orderBy) + + const handleOpen = (value) => { + setOpen(open === value ? 0 : value) + } + const orderOptions = [ + { value: 'price-asc', label: 'Harga Terendah' }, + { value: 'price-desc', label: 'Harga Tertinggi' }, + { value: 'popular', label: 'Populer' }, + { value: 'stock', label: 'Ready Stock' } + ] + + const handleOrderBy = (e) => { + let params = { + ...router.query, + orderBy: e.target.value + } + params = _.pickBy(params, _.identity) + params = toQuery(params) + router.push(`${prefixUrl}?${params}`) + } + useEffect(() => { if (!products) { setProducts(productSearch.data?.response?.products) @@ -46,70 +76,180 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => { } return ( -
-

Produk

- -
- {productFound > 0 ? ( - <> - Menampilkan  - {pageCount > 1 ? ( + <> + +
+

Produk

+ +
+ {productFound > 0 ? ( <> - {productStart + 1}- - {productStart + productRows > productFound - ? productFound - : productStart + productRows} -  dari  + Menampilkan  + {pageCount > 1 ? ( + <> + {productStart + 1}- + {productStart + productRows > productFound + ? productFound + : productStart + productRows} +  dari  + + ) : ( + '' + )} + {productFound} +  produk{' '} + {query.q && ( + <> + untuk pencarian {query.q} + + )} ) : ( - '' + 'Mungkin yang anda cari' )} - {productFound} -  produk{' '} - {query.q && ( - <> - untuk pencarian {query.q} - - )} - - ) : ( - 'Mungkin yang anda cari' - )} -
- - - -
- {products && - products.map((product) => ( - + + + +
+ {products && + products.map((product) => ( + + ))} +
+ + + + +
+ + +
+
+ - ))} -
- - - - -
+
+
+

Hasil Pencarian

+
+
+ {productFound > 0 ? ( + <> + Menampilkan  + {pageCount > 1 ? ( + <> + {productStart + 1}- + {productStart + productRows > productFound + ? productFound + : productStart + productRows} +  dari  + + ) : ( + '' + )} + {productFound} +  produk{' '} + {query.q && ( + <> + untuk pencarian {query.q} + + )} + + ) : ( + 'Mungkin yang anda cari' + )} +
+
+ {/*
+ +
*/} +
+ +
+
+
+
+ {products && + products.map((product) => ( + + ))} +
+
+
+ +
+ + Barang yang anda cari tidak ada?{' '} + + Hubungi Kami + + +
+
+ + +
+
+
+ + ) } diff --git a/tailwind.config.js b/tailwind.config.js index 95570311..f4335eb8 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,12 @@ /** @type {import('tailwindcss').Config} */ -module.exports = { - content: ['./src/**/*.{js,ts,jsx,tsx}'], +const withMT = require("@material-tailwind/react/utils/withMT"); +module.exports = withMT({ + content: [ + "./node_modules/flowbite-react/**/*.js", + './src/**/*.{js,ts,jsx,tsx}'], + plugins: [ + require("flowbite/plugin") + ], theme: { extend: { container: { @@ -103,4 +109,4 @@ module.exports = { } }, plugins: [require('@tailwindcss/line-clamp'), require('@tailwindcss/typography')] -} +}) -- cgit v1.2.3