1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
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();
const data = result.data || [];
data.sort((a, b) => (a.sequence || 0) - (b.sequence || 0));
setMedia(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;
|