From 60e116965f42e7e8944c0adcc4bc7bc5fc3a485a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 6 Aug 2025 10:58:15 +0700 Subject: media banner --- src/lib/home/api/mediaNews.js | 0 src/lib/home/components/MediaNews.jsx | 107 ++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/lib/home/api/mediaNews.js create mode 100644 src/lib/home/components/MediaNews.jsx diff --git a/src/lib/home/api/mediaNews.js b/src/lib/home/api/mediaNews.js new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx new file mode 100644 index 00000000..1e538d48 --- /dev/null +++ b/src/lib/home/components/MediaNews.jsx @@ -0,0 +1,107 @@ +import Link from '@/core/components/elements/Link/Link'; +import Image from 'next/image'; +import { bannerApi } from '@/api/bannerApi'; +import useDevice from '@/core/hooks/useDevice'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import BannerPromoSkeleton from '../components/Skeleton/BannerPromoSkeleton'; + +import { useEffect, useState } from 'react'; +const { useQuery } = require('react-query'); +const BannerSection = () => { + const { isMobile, isDesktop } = useDevice(); + const [data, setData] = useState(null); + const [shouldFetch, setShouldFetch] = useState(false); + const [ isLoading, setIsLoading] = useState(true); + useEffect(() => { + const fetchData = async () => { + try { + const res = await fetch(`/api/hero-banner?type=banner-promotion`); + const { data } = await res.json(); + if (data) { + setData(data); + } + } catch (e) { + console.log(e); + } finally { + setIsLoading(false); + } + }; + + fetchData(); + }, []); + + const promotionProgram = data; + + if (isLoading) { + return ; + } + + if (!promotionProgram || promotionProgram.length === 0) { + return null; + } + + return ( +
+
+

+ {' '} + + Promo Tersedia + +

+ {isDesktop && ( + + Lihat Semua + + )} + {isMobile && ( + + Lihat Semua + + )} +
+ {isDesktop && promotionProgram && promotionProgram?.length > 0 && ( +
+ {promotionProgram?.map((banner) => ( + + {banner.name} + + ))} +
+ )} + + {isMobile && ( + + {promotionProgram?.map((banner) => ( + + + {banner.name} + + + ))} + + )} +
+ ); +}; + +export default BannerSection; -- cgit v1.2.3 From d32ed92902d52934a55cdb9efe110ef11cd920d8 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 16 Aug 2025 09:52:55 +0700 Subject: (andri) make component card mediacard --- src/lib/brand/components/BrandCard.jsx | 1 + src/lib/brand/components/MediaCard.jsx | 42 +++++++ src/lib/home/components/MediaNews.jsx | 137 ++++++++------------- .../home/components/Skeleton/MediaNewsSkeleton.jsx | 21 ++++ src/pages/index.jsx | 3 + 5 files changed, 119 insertions(+), 85 deletions(-) create mode 100644 src/lib/brand/components/MediaCard.jsx create mode 100644 src/lib/home/components/Skeleton/MediaNewsSkeleton.jsx diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx index dff61b24..411e2669 100644 --- a/src/lib/brand/components/BrandCard.jsx +++ b/src/lib/brand/components/BrandCard.jsx @@ -5,6 +5,7 @@ import { createSlug } from '@/core/utils/slug'; const BrandCard = ({ brand }) => { const { isMobile } = useDevice(); + // console.log("Brand logo:", brand.logo); return ( { + const { isMobile } = useDevice(); + +// console.log("Media logo:", media); + + return ( + + {media.image ? ( + + ) : ( + + {media.name} + + )} + + ); +}; + +export default MediaCard; diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index 1e538d48..1c76398f 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -1,101 +1,68 @@ -import Link from '@/core/components/elements/Link/Link'; -import Image from 'next/image'; -import { bannerApi } from '@/api/bannerApi'; -import useDevice from '@/core/hooks/useDevice'; import { Swiper, SwiperSlide } from 'swiper/react'; -import BannerPromoSkeleton from '../components/Skeleton/BannerPromoSkeleton'; +import { Navigation, Pagination, Autoplay } from 'swiper'; +import { useEffect, useState, useCallback } from 'react'; +import MediaNewsSkeleton from './Skeleton/MediaNewsSkeleton'; +import MediaCard from '@/lib/brand/components/MediaCard'; +import useDevice from '@/core/hooks/useDevice'; +import Link from '@/core/components/elements/Link/Link'; -import { useEffect, useState } from 'react'; -const { useQuery } = require('react-query'); -const BannerSection = () => { +const MediaNews = () => { + const [isLoading, setIsLoading] = useState(true); + const [media, setMedia] = useState([]); const { isMobile, isDesktop } = useDevice(); - const [data, setData] = useState(null); - const [shouldFetch, setShouldFetch] = useState(false); - const [ isLoading, setIsLoading] = useState(true); - useEffect(() => { - const fetchData = async () => { - try { - const res = await fetch(`/api/hero-banner?type=banner-promotion`); - const { data } = await res.json(); - if (data) { - setData(data); - } - } catch (e) { - console.log(e); - } finally { - setIsLoading(false); - } - }; - fetchData(); + const loadMedia = useCallback(async () => { + try { + setIsLoading(true); + const res = await fetch(`/api/hero-banner?type=media-berita`); + const result = await res.json(); + setMedia(result.data || []); + } catch (err) { + console.error('Failed to load media:', err); + } finally { + setIsLoading(false); + } }, []); - const promotionProgram = data; + useEffect(() => { + loadMedia(); + }, [loadMedia]); - if (isLoading) { - return ; - } + const swiperConfig = { + modules: [Navigation, Pagination, Autoplay], + autoplay: { delay: 4000, disableOnInteraction: false }, + loop: true, + className: 'h-[70px] md:h-[100px] w-full', + slidesPerView: isMobile ? 4 : 8, + spaceBetween: isMobile ? 12 : 0, + pagination: { dynamicBullets: true, dynamicMainBullets: isMobile ? 6 : 8, clickable: true }, + }; - if (!promotionProgram || promotionProgram.length === 0) { - return null; - } + const preferredMediaData = media.slice(0, 20); return ( -
-
-

- {' '} - - Promo Tersedia +
+
+

+ + Media Berita

- {isDesktop && ( - - Lihat Semua - - )} - {isMobile && ( - - Lihat Semua - - )} + + Lihat Semua +
- {isDesktop && promotionProgram && promotionProgram?.length > 0 && ( -
- {promotionProgram?.map((banner) => ( - - {banner.name} - - ))} -
- )} - {isMobile && ( - - {promotionProgram?.map((banner) => ( - - - {banner.name} - + {isLoading ? ( + + ) : ( + + {preferredMediaData.map((item) => ( + + ))} @@ -104,4 +71,4 @@ const BannerSection = () => { ); }; -export default BannerSection; +export default MediaNews; diff --git a/src/lib/home/components/Skeleton/MediaNewsSkeleton.jsx b/src/lib/home/components/Skeleton/MediaNewsSkeleton.jsx new file mode 100644 index 00000000..c0151efd --- /dev/null +++ b/src/lib/home/components/Skeleton/MediaNewsSkeleton.jsx @@ -0,0 +1,21 @@ +import useDevice from '@/core/hooks/useDevice' +import Skeleton from 'react-loading-skeleton' + +const MediaNewsSkeleton = () => { + const { isDesktop } = useDevice() + + return ( +
+ {Array.from({ length: isDesktop ? 8 : 4 }, (_, index) => ( + + ))} +
+ ) +} + +export default MediaNewsSkeleton diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 809f00ae..bb375c53 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -9,6 +9,7 @@ import PagePopupInformation from '@/lib/home/components/PopupBannerPromotion'; import dynamic from 'next/dynamic'; import { useRef } from 'react'; import { getAuth } from '~/libs/auth'; +import MediaNews from '../lib/home/components/MediaNews'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -138,6 +139,7 @@ export default function Home({ categoryId }) {
+
@@ -168,6 +170,7 @@ export default function Home({ categoryId }) {
+ -- cgit v1.2.3 From 8492e0bccb64265d647efb34062787f56a2ddeb8 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 16 Aug 2025 10:51:54 +0700 Subject: (andri) filter swiper only > 8 desktop --- src/lib/home/components/MediaNews.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index 1c76398f..ec27a51d 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -40,12 +40,14 @@ const MediaNews = () => { const preferredMediaData = media.slice(0, 20); + const shouldUseSlider = isDesktop && preferredMediaData.length > 8; + return (

- Media Berita + Media Partner

{ {isLoading ? ( - ) : ( + ) : shouldUseSlider ? ( {preferredMediaData.map((item) => ( @@ -66,6 +68,12 @@ const MediaNews = () => { ))} + ) : ( +
+ {preferredMediaData.map((item) => ( + + ))} +
)}
); -- cgit v1.2.3 From 8045280d780061e1829fe596410356589e323fb6 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 16 Aug 2025 11:46:59 +0700 Subject: (andri) fix --- src/lib/home/components/MediaNews.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index ec27a51d..116dda2b 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -40,7 +40,7 @@ const MediaNews = () => { const preferredMediaData = media.slice(0, 20); - const shouldUseSlider = isDesktop && preferredMediaData.length > 8; + const shouldUseSlider = isMobile || (isDesktop && preferredMediaData.length > 8); return (
-- cgit v1.2.3 From 4690139fb33be48ca49cca1b3d270941a0a5e89a Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 16 Aug 2025 13:21:29 +0700 Subject: (andri) fix --- src/lib/home/components/MediaNews.jsx | 2 +- src/pages/index.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index 116dda2b..ac56d4e3 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -47,7 +47,7 @@ const MediaNews = () => {

- Media Partner + Telah Diliput Media

- +
@@ -170,8 +170,8 @@ export default function Home({ categoryId }) {
- +
-- cgit v1.2.3 From 4e7854765e66b27246b9dafc0177905d707d0cd1 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 16 Aug 2025 14:33:24 +0700 Subject: (andri) fix --- src/lib/home/components/MediaNews.jsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index ac56d4e3..528fbe7c 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -46,16 +46,10 @@ const MediaNews = () => {

- + Telah Diliput Media

- - Lihat Semua -
{isLoading ? ( -- cgit v1.2.3 From 9fa82a1c56e6e1628ef5a255ba3f66fb6aec83ec Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Mon, 25 Aug 2025 16:07:26 +0700 Subject: (andri) tidak render media jika tidak ada data --- src/lib/home/components/MediaNews.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx index 528fbe7c..6a0efbfe 100644 --- a/src/lib/home/components/MediaNews.jsx +++ b/src/lib/home/components/MediaNews.jsx @@ -42,6 +42,10 @@ const MediaNews = () => { const shouldUseSlider = isMobile || (isDesktop && preferredMediaData.length > 8); + if (!isLoading && preferredMediaData.length === 0) { + return null; + } + return (
-- cgit v1.2.3