summaryrefslogtreecommitdiff
path: root/src/lib/brand
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/brand')
-rw-r--r--src/lib/brand/api/BrandApi.js8
-rw-r--r--src/lib/brand/components/Brand.jsx70
-rw-r--r--src/lib/brand/components/BrandCard.jsx30
-rw-r--r--src/lib/brand/components/Brands.jsx80
-rw-r--r--src/lib/brand/hooks/useBrand.js13
5 files changed, 201 insertions, 0 deletions
diff --git a/src/lib/brand/api/BrandApi.js b/src/lib/brand/api/BrandApi.js
new file mode 100644
index 00000000..79801774
--- /dev/null
+++ b/src/lib/brand/api/BrandApi.js
@@ -0,0 +1,8 @@
+import odooApi from '@/core/api/odooApi'
+
+const BrandApi = async ({ id }) => {
+ const dataBrand = await odooApi('GET', `/api/v1/manufacture/${id}`)
+ return dataBrand
+}
+
+export default BrandApi
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
diff --git a/src/lib/brand/hooks/useBrand.js b/src/lib/brand/hooks/useBrand.js
new file mode 100644
index 00000000..3ba65a97
--- /dev/null
+++ b/src/lib/brand/hooks/useBrand.js
@@ -0,0 +1,13 @@
+import { useQuery } from 'react-query'
+import BrandApi from '../api/BrandApi'
+
+const useBrand = ({ id }) => {
+ const fetchBrand = async () => await BrandApi({ id })
+ const { data, isLoading } = useQuery(`brand-${id}`, fetchBrand)
+
+ return {
+ brand: { data, isLoading }
+ }
+}
+
+export default useBrand