208 lines
5.8 KiB
TypeScript
208 lines
5.8 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, useState } from "react";
|
|
import Image from "next/image";
|
|
import { getListArticle } from "@/service/article";
|
|
|
|
type Article = {
|
|
id: number;
|
|
title: string;
|
|
description: string;
|
|
categoryName: string;
|
|
createdAt: string;
|
|
createdByName: string;
|
|
thumbnailUrl: string;
|
|
categories: {
|
|
title: string;
|
|
}[];
|
|
files: {
|
|
fileUrl: string;
|
|
file_alt: string;
|
|
}[];
|
|
};
|
|
|
|
export default function BreakingNews() {
|
|
const [articles, setArticles] = useState<Article[]>([]);
|
|
const [popular, setPopular] = useState<Article[]>([]);
|
|
|
|
useEffect(() => {
|
|
fetchArticles();
|
|
fetchPopular();
|
|
}, []);
|
|
|
|
async function fetchArticles() {
|
|
try {
|
|
const req = {
|
|
limit: "5",
|
|
page: 1,
|
|
search: "",
|
|
categorySlug: "",
|
|
sort: "desc",
|
|
isPublish: true,
|
|
sortBy: "created_at",
|
|
};
|
|
const res = await getListArticle(req);
|
|
setArticles(res?.data?.data || []);
|
|
} catch (error) {
|
|
console.error("Gagal memuat artikel:", error);
|
|
}
|
|
}
|
|
|
|
async function fetchPopular() {
|
|
try {
|
|
const req = {
|
|
limit: "5",
|
|
page: 1,
|
|
search: "",
|
|
categorySlug: "",
|
|
sort: "",
|
|
isPublish: true,
|
|
sortBy: "",
|
|
};
|
|
const res = await getListArticle(req);
|
|
setPopular(res?.data?.data || []);
|
|
} catch (error) {
|
|
console.error("Gagal memuat artikel populer:", error);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<section className="max-w-screen-xl mx-auto px-3 md:px-5 py-8 grid grid-cols-1 md:grid-cols-4 gap-6">
|
|
{/* Kiri - Breaking News */}
|
|
<div className="md:col-span-2 space-y-6">
|
|
{articles.map((item) => (
|
|
<div key={item.id} className="flex gap-4 border-b pb-4">
|
|
<Image
|
|
src={item.thumbnailUrl || "/dummy.jpg"}
|
|
alt={item.title}
|
|
width={160}
|
|
height={100}
|
|
className="object-cover rounded-md w-40 h-28"
|
|
/>
|
|
<div className="flex-1">
|
|
<h3 className="text-base font-semibold hover:text-blue-600 cursor-pointer">
|
|
{item.title}
|
|
</h3>
|
|
<p className="text-xs text-gray-500 mt-1">
|
|
By {item.createdByName} •{" "}
|
|
{new Date(item.createdAt).toLocaleDateString("id-ID", {
|
|
day: "numeric",
|
|
month: "long",
|
|
year: "numeric",
|
|
})}
|
|
</p>
|
|
<p className="text-sm text-gray-600 mt-2 line-clamp-2">
|
|
{item.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Tengah - Browse Categories & Topics (dummy) */}
|
|
<div className="space-y-8">
|
|
<div>
|
|
<h4 className="font-bold text-gray-800 border-b pb-2 mb-3">
|
|
BROWSE BY CATEGORIES
|
|
</h4>
|
|
<ul className="space-y-2 text-sm text-gray-600">
|
|
<li>Berita Opini</li>
|
|
<li>Berita Populer</li>
|
|
<li>Berita Terkini</li>
|
|
<li>Jaga Negeri</li>
|
|
<li>National</li>
|
|
<li>Politics</li>
|
|
<li>Ragam Nusantara</li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 className="font-bold text-gray-800 border-b pb-2 mb-3">
|
|
BROWSE BY TOPICS
|
|
</h4>
|
|
<div className="flex flex-wrap gap-2 text-xs">
|
|
{[
|
|
"#GIIAS2025",
|
|
"#mdtranscorp",
|
|
"2018 League",
|
|
"Bali United",
|
|
"Chopper Bike",
|
|
].map((topic, i) => (
|
|
<span
|
|
key={i}
|
|
className="bg-gray-100 px-2 py-1 rounded-md cursor-pointer hover:bg-gray-200"
|
|
>
|
|
{topic}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Kanan - Popular News */}
|
|
<div>
|
|
<h4 className="font-bold text-blue-700 border-b pb-2 mb-3">
|
|
POPULAR NEWS
|
|
</h4>
|
|
|
|
{popular.length > 0 && (
|
|
<div className="space-y-5">
|
|
{/* Item pertama tampil besar */}
|
|
<div className="relative">
|
|
<Image
|
|
src={popular[0]?.files?.[0]?.fileUrl || "/dummy.jpg"}
|
|
alt={
|
|
popular[0]?.files?.[0]?.file_alt ||
|
|
popular[0]?.title ||
|
|
"No Title"
|
|
}
|
|
width={400}
|
|
height={200}
|
|
className="w-full h-48 object-cover rounded-md"
|
|
/>
|
|
<div className="mt-2">
|
|
<h5 className="text-sm font-semibold hover:text-blue-600 cursor-pointer">
|
|
{popular[0]?.title}
|
|
</h5>
|
|
<span className="absolute top-2 right-2 text-4xl font-bold text-gray-300/80">
|
|
01
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Item sisanya */}
|
|
<div className="space-y-4">
|
|
{popular.slice(1).map((item, i) => (
|
|
<div
|
|
key={item.id}
|
|
className="flex gap-3 items-start border-b pb-2 last:border-b-0"
|
|
>
|
|
<span className="text-lg font-bold text-gray-400">
|
|
0{i + 2}
|
|
</span>
|
|
<div>
|
|
<h5 className="text-sm font-medium hover:text-blue-600 cursor-pointer">
|
|
{item.title}
|
|
</h5>
|
|
<p className="text-xs text-gray-400">0 Shares</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Advert */}
|
|
<div className="mt-6">
|
|
<Image
|
|
src="/adversment.png"
|
|
alt="Advertisement"
|
|
width={300}
|
|
height={250}
|
|
className="mx-auto"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|