diff options
Diffstat (limited to 'src/lib/home/components/MediaNews.jsx')
| -rw-r--r-- | src/lib/home/components/MediaNews.jsx | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/lib/home/components/MediaNews.jsx b/src/lib/home/components/MediaNews.jsx new file mode 100644 index 00000000..6a0efbfe --- /dev/null +++ b/src/lib/home/components/MediaNews.jsx @@ -0,0 +1,80 @@ +import { Swiper, SwiperSlide } from 'swiper/react'; +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'; + +const MediaNews = () => { + const [isLoading, setIsLoading] = useState(true); + const [media, setMedia] = useState([]); + const { isMobile, isDesktop } = useDevice(); + + 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); + } + }, []); + + useEffect(() => { + loadMedia(); + }, [loadMedia]); + + 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 }, + }; + + const preferredMediaData = media.slice(0, 20); + + const shouldUseSlider = isMobile || (isDesktop && preferredMediaData.length > 8); + + if (!isLoading && preferredMediaData.length === 0) { + return null; + } + + return ( + <div className="px-4 sm:px-0"> + <div className="flex justify-between items-center mb-4"> + <h1 className="font-semibold text-[14px] sm:text-h-lg"> + <Link href="/" className="!text-black font-semibold"> + Telah Diliput Media + </Link> + </h1> + </div> + + {isLoading ? ( + <MediaNewsSkeleton /> + ) : shouldUseSlider ? ( + <Swiper {...swiperConfig}> + {preferredMediaData.map((item) => ( + <SwiperSlide key={item.id}> + <MediaCard media={item} /> + </SwiperSlide> + ))} + </Swiper> + ) : ( + <div className="flex flex-wrap justify-center gap-4"> + {preferredMediaData.map((item) => ( + <MediaCard key={item.id} media={item} /> + ))} + </div> + )} + </div> + ); +}; + +export default MediaNews; |
