summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/home/components/BannerSection.jsx158
-rw-r--r--src/lib/home/components/CategoryHomeId.jsx2
-rw-r--r--src/pages/api/banner-section.js74
3 files changed, 178 insertions, 56 deletions
diff --git a/src/lib/home/components/BannerSection.jsx b/src/lib/home/components/BannerSection.jsx
index 898f1bf5..1eac9592 100644
--- a/src/lib/home/components/BannerSection.jsx
+++ b/src/lib/home/components/BannerSection.jsx
@@ -1,62 +1,126 @@
import Link from '@/core/components/elements/Link/Link';
-import Image from 'next/image';
import { useEffect, useState } from 'react';
-import { bannerApi } from '../../../api/bannerApi';
-
-const { useQuery } = require('react-query');
-const { default: bannerSectionApi } = require('../api/bannerSectionApi');
+import useDevice from '@/core/hooks/useDevice';
+import { Swiper, SwiperSlide } from 'swiper/react';
const BannerSection = () => {
- const [data, setData] = useState(null);
- const [shouldFetch, setShouldFetch] = useState(false);
-
+ const [privateBrandData, setPrivateBrandData] = useState([]);
+ const [homeBannerData, setHomeBannerData] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const { isMobile, isDesktop } = useDevice();
useEffect(() => {
- const fetchCategoryData = async () => {
- const res = await fetch('/api/banner-section');
- const { data } = await res.json();
- if (data) {
- setData(data);
+ const fetchAllBanners = async () => {
+ try {
+ // Fetch private brand banners
+ const privateBrandRes = await fetch(
+ '/api/banner-section?type=private-brand'
+ );
+ if (privateBrandRes.ok) {
+ const privateBrandResult = await privateBrandRes.json();
+ setPrivateBrandData(privateBrandResult.data || []);
+ }
+
+ // Fetch home banners
+ const homeBannerRes = await fetch(
+ '/api/banner-section?type=home-banner'
+ );
+ if (homeBannerRes.ok) {
+ const homeBannerResult = await homeBannerRes.json();
+ setHomeBannerData(homeBannerResult.data || []);
+ }
+ } catch (err) {
+ setError('Network error');
+ } finally {
+ setLoading(false);
}
};
- fetchCategoryData();
+ fetchAllBanners();
}, []);
- // const fetchBannerSection = async () => await bannerSectionApi();
- const getBannerSection = useQuery(
- 'bannerSection',
- bannerApi({ type: 'home-banner' }),
- {
- enabled: shouldFetch,
- onSuccess: (data) => {
- if (data) {
- localStorage.setItem('Homepage_bannerSection', JSON.stringify(data));
- setData(data);
- }
- },
- }
- );
+ // if (loading) return <div>Loading...</div>;
+ // if (error) return <div>Error: {error}</div>;
- const bannerSection = data;
return (
- bannerSection &&
- bannerSection?.length > 0 && (
- <div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
- {bannerSection?.map((banner) => (
- <Link key={banner.id} href={banner.url}>
- <Image
- width={1024}
- height={512}
- quality={85}
- src={banner.image}
- alt={banner.name}
- className='h-auto w-full rounded'
- loading='eager'
- />
- </Link>
- ))}
- </div>
- )
+ <div className='space-y-12'>
+ {/* Private Brand Section */}
+ {privateBrandData && privateBrandData.length > 0 && (
+ <div className='px-4 sm:px-0'>
+ <div
+ className='text-black font-semibold sm:text-h-lg mb-6'
+ id='private-brand'
+ >
+ Private Brand
+ </div>
+
+ {/* Desktop Grid View */}
+ {isDesktop && (
+ <div className='grid grid-cols-3 sm:grid-cols-3 gap-4 rounded-md'>
+ {privateBrandData.map((banner, index) => (
+ <Link key={banner.id || index} href={banner.url || '#'}>
+ <img
+ width={439}
+ height={150}
+ quality={85}
+ src={banner.image}
+ alt={banner.name || `Private Brand Banner ${index + 1}`}
+ className='rounded hover:scale-105 transition duration-500 ease-in-out'
+ loading='eager'
+ />
+ </Link>
+ ))}
+ </div>
+ )}
+
+ {/* Mobile Swiper View */}
+ {isMobile && (
+ <Swiper slidesPerView={1.1} spaceBetween={8} freeMode>
+ {privateBrandData.map((banner, index) => (
+ <SwiperSlide key={banner.id || index}>
+ <Link href={banner.url || '#'}>
+ <img
+ width={350}
+ height={100}
+ quality={70}
+ src={banner.image}
+ alt={banner.name || `Private Brand Banner ${index + 1}`}
+ className='rounded'
+ loading='eager'
+ />
+ </Link>
+ </SwiperSlide>
+ ))}
+ </Swiper>
+ )}
+ </div>
+ )}
+
+ {/* Home Banner Section */}
+ {homeBannerData && homeBannerData.length > 0 && (
+ <div className='grid grid-cols-1 sm:grid-cols-2 gap-4'>
+ {homeBannerData.map((banner, index) => (
+ <div key={banner.id || index} className='relative'>
+ <Link href={banner.url || '#'}>
+ <img
+ width={1024}
+ height={512}
+ quality={85}
+ src={banner.image}
+ alt={banner.name || `Home Banner ${index + 1}`}
+ // className='h-40 w-full rounded object-cover transition-transform hover:scale-105'
+ className='h-auto w-full rounded'
+ loading='eager'
+ onError={(e) => {
+ e.target.style.display = 'none';
+ }}
+ />
+ </Link>
+ </div>
+ ))}
+ </div>
+ )}
+ </div>
);
};
diff --git a/src/lib/home/components/CategoryHomeId.jsx b/src/lib/home/components/CategoryHomeId.jsx
index 9f436dac..db473a1c 100644
--- a/src/lib/home/components/CategoryHomeId.jsx
+++ b/src/lib/home/components/CategoryHomeId.jsx
@@ -8,7 +8,7 @@ const CategoryHomeId = () => {
return (
<div>
<h1 className='font-semibold text-[14px] sm:text-h-lg mb-6 px-4 sm:px-0'>
- Kategori Pilihan
+ Paket Bundling / Paket UMKM
</h1>
<div className='flex flex-col gap-y-10'>
{categoryHomeIds.data?.map((id) => (
diff --git a/src/pages/api/banner-section.js b/src/pages/api/banner-section.js
index 7d7040c0..ab48f3f4 100644
--- a/src/pages/api/banner-section.js
+++ b/src/pages/api/banner-section.js
@@ -12,22 +12,81 @@ const connectRedis = async () => {
};
export default async function handler(req, res) {
+ if (req.method !== 'GET') {
+ return res.status(405).json({ error: 'Method not allowed' });
+ }
+
try {
await connectRedis();
- const cacheKey = 'hero-banner';
- // await client.del(cacheKey);
+
+ const type = req.query.type || 'home-banner';
+
+ if (type === 'private-brand') {
+ // Handle multiple private brand banner types
+ const bannerTypes = [
+ 'banner-brand-footer',
+ 'banner-brand-tengah-footer',
+ 'banner-brand-kanan-footer',
+ ];
+
+ const allBanners = [];
+
+ for (const brandType of bannerTypes) {
+ const brandCacheKey = `homepage_bannerSection_${brandType}`;
+
+ let cachedData = await client.get(brandCacheKey);
+
+ if (cachedData) {
+ const data = JSON.parse(cachedData);
+ allBanners.push(...(data || []));
+ } else {
+ try {
+ const dataBannerSections = await odooApi(
+ 'GET',
+ `/api/v1/banner?type=${brandType}`
+ );
+
+ if (dataBannerSections && dataBannerSections.length > 0) {
+ await client.set(
+ brandCacheKey,
+ JSON.stringify(dataBannerSections),
+ 'EX',
+ 259200
+ );
+ allBanners.push(...dataBannerSections);
+ }
+ } catch (error) {
+ continue;
+ }
+ }
+ }
+
+ return res.status(200).json({
+ data: allBanners,
+ total: allBanners.length,
+ });
+ }
+
+ // Handle home-banner and other single types
+ let cacheKey;
+ let apiEndpoint;
+
+ if (type === 'home-banner') {
+ cacheKey = 'hero-banner';
+ apiEndpoint = '/api/v1/banner?type=home-banner';
+ } else {
+ cacheKey = `homepage_bannerSection_${type}`;
+ apiEndpoint = `/api/v1/banner?type=${type}`;
+ }
+
let cachedData = await client.get(cacheKey);
if (cachedData) {
const data = JSON.parse(cachedData);
return res.status(200).json({ data });
} else {
- const dataBannerSections = await odooApi(
- 'GET',
- '/api/v1/banner?type=home-banner'
- );
+ const dataBannerSections = await odooApi('GET', apiEndpoint);
- // Simpan hasil fetch ke Redis dengan masa kadaluarsa 3 hari (259200 detik)
await client.set(
cacheKey,
JSON.stringify(dataBannerSections),
@@ -38,7 +97,6 @@ export default async function handler(req, res) {
return res.status(200).json({ data: dataBannerSections });
}
} catch (error) {
- console.error('Error interacting with Redis or fetching data:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
}