diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2023-03-01 09:18:52 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2023-03-01 09:18:52 +0000 |
| commit | a7abbf4ddc70068620e9f44b74dc162ce2e16ee2 (patch) | |
| tree | 74f66253717515d364ce74bd8275015c1f829cbc /src/lib/brand/components | |
| parent | 90e1edab9b6a8ccc09a49fed3addbec2cbc4e4c3 (diff) | |
| parent | a1b9b647a6c4bda1f5db63879639d44543f9557e (diff) | |
Merged in refactor (pull request #1)
Refactor
Diffstat (limited to 'src/lib/brand/components')
| -rw-r--r-- | src/lib/brand/components/Brand.jsx | 70 | ||||
| -rw-r--r-- | src/lib/brand/components/BrandCard.jsx | 30 | ||||
| -rw-r--r-- | src/lib/brand/components/Brands.jsx | 80 |
3 files changed, 180 insertions, 0 deletions
diff --git a/src/lib/brand/components/Brand.jsx b/src/lib/brand/components/Brand.jsx new file mode 100644 index 00000000..c338c4c4 --- /dev/null +++ b/src/lib/brand/components/Brand.jsx @@ -0,0 +1,70 @@ +import useBrand from '../hooks/useBrand' +import Image from '@/core/components/elements/Image/Image' + +import { Swiper, SwiperSlide } from 'swiper/react' +import { Pagination, Autoplay } from 'swiper' +import 'swiper/css' +import 'swiper/css/pagination' +import 'swiper/css/autoplay' +import Divider from '@/core/components/elements/Divider/Divider' +import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' + +const swiperBanner = { + pagination: { dynamicBullets: true }, + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + modules: [Pagination, Autoplay] +} + +const Brand = ({ id }) => { + const { brand } = useBrand({ id }) + + return ( + <> + <div className='min-h-[150px]'> + {brand.isLoading && <ImageSkeleton />} + {brand.data && ( + <> + <Swiper + slidesPerView={1} + pagination={swiperBanner.pagination} + modules={swiperBanner.modules} + autoplay={swiperBanner.autoplay} + className='border-b border-gray_r-6' + > + {brand.data?.banners?.map((banner, index) => ( + <SwiperSlide key={index}> + <Image + src={banner} + alt={`Brand ${brand.data?.name} - Indoteknik`} + className='w-full h-auto' + /> + </SwiperSlide> + ))} + </Swiper> + <div className='p-4'> + <div className='text-caption-1 text-gray_r-11 mb-2'>Produk dari brand:</div> + {brand?.data?.logo && ( + <Image + src={brand?.data?.logo} + alt={brand?.data?.name} + className='w-32 p-2 border borde-gray_r-6 rounded' + /> + )} + {!brand?.data?.logo && ( + <div className='bg-red_r-10 text-white text-center text-caption-1 py-2 px-4 rounded w-fit'> + {brand?.data?.name} + </div> + )} + </div> + </> + )} + </div> + <Divider /> + </> + ) +} + +export default Brand diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx new file mode 100644 index 00000000..1bcdb5ab --- /dev/null +++ b/src/lib/brand/components/BrandCard.jsx @@ -0,0 +1,30 @@ +import Image from '@/core/components/elements/Image/Image' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' + +const BrandCard = ({ brand }) => { + return ( + <Link + href={createSlug('/shop/brands/', brand.name, brand.id)} + className='py-1 px-2 rounded border border-gray_r-6 h-12 flex justify-center items-center' + > + {brand.logo && ( + <Image + src={brand.logo} + alt={brand.name} + className='h-full object-contain object-center' + /> + )} + {!brand.logo && ( + <span + className='text-center' + style={{ fontSize: `${14 - brand.name.length * 0.5}px` }} + > + {brand.name} + </span> + )} + </Link> + ) +} + +export default BrandCard diff --git a/src/lib/brand/components/Brands.jsx b/src/lib/brand/components/Brands.jsx new file mode 100644 index 00000000..22f47975 --- /dev/null +++ b/src/lib/brand/components/Brands.jsx @@ -0,0 +1,80 @@ +import odooApi from '@/core/api/odooApi' +import Spinner from '@/core/components/elements/Spinner/Spinner' +import { useCallback, useEffect, useState } from 'react' +import BrandCard from './BrandCard' + +const Brands = () => { + const alpha = Array.from(Array(26)).map((e, i) => i + 65) + const alphabets = alpha.map((x) => String.fromCharCode(x)) + + const [isLoading, setIsLoading] = useState(true) + const [startWith, setStartWith] = useState(null) + const [manufactures, setManufactures] = useState([]) + + const loadBrand = useCallback(async () => { + setIsLoading(true) + const name = startWith ? `${startWith}%` : '' + const result = await odooApi( + 'GET', + `/api/v1/manufacture?limit=0&offset=${manufactures.length}&name=${name}` + ) + setIsLoading(false) + setManufactures((manufactures) => [...manufactures, ...result.manufactures]) + }, [startWith]) + + const toggleStartWith = (alphabet) => { + setManufactures([]) + if (alphabet == startWith) { + setStartWith(null) + return + } + setStartWith(alphabet) + } + + useEffect(() => { + loadBrand() + }, [loadBrand]) + + if (isLoading) { + return ( + <div className='flex justify-center my-4'> + <Spinner className='w-6 text-gray_r-12/50 fill-gray_r-12' /> + </div> + ) + } + + return ( + <div className='p-4'> + <h1 className='font-semibold'>Semua Brand di Indoteknik</h1> + <div className='flex overflow-x-auto gap-x-2 py-2'> + {alphabets.map((alphabet, index) => ( + <button + key={index} + className={ + 'p-2 py-1 border bg-white border-gray_r-6 rounded w-10 flex-shrink-0' + + (startWith == alphabet ? ' !bg-yellow_r-9 border-yellow_r-9 ' : '') + } + type='button' + onClick={() => toggleStartWith(alphabet)} + > + {alphabet} + </button> + ))} + </div> + + <div className='grid grid-cols-4 gap-4 mt-4 !overflow-x-hidden'> + {manufactures?.map( + (manufacture, index) => + manufacture.name && ( + <BrandCard + brand={manufacture} + key={index} + /> + ) + )} + </div> + </div> + ) +} + +export default Brands |
