98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useEffect, useState } from "react";
|
||
|
|
import Image from "next/image";
|
||
|
|
import { getListArticle } from "@/service/article";
|
||
|
|
import Link from "next/link";
|
||
|
|
|
||
|
|
type Article = {
|
||
|
|
id: number;
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
categoryName: string;
|
||
|
|
createdAt: string;
|
||
|
|
createdByName: string;
|
||
|
|
customCreatorName: string;
|
||
|
|
thumbnailUrl: string;
|
||
|
|
categories: { title: string }[];
|
||
|
|
files: { fileUrl: string; file_alt: string }[];
|
||
|
|
};
|
||
|
|
|
||
|
|
export default function Header() {
|
||
|
|
const [articles, setArticles] = useState<Article[]>([]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const fetchArticles = async () => {
|
||
|
|
try {
|
||
|
|
const req = {
|
||
|
|
limit: "5", // tampilkan 5 artikel seperti data dummy sebelumnya
|
||
|
|
page: 1,
|
||
|
|
search: "",
|
||
|
|
categorySlug: "",
|
||
|
|
sort: "desc",
|
||
|
|
isPublish: true,
|
||
|
|
sortBy: "created_at",
|
||
|
|
};
|
||
|
|
|
||
|
|
const res = await getListArticle(req);
|
||
|
|
setArticles(res?.data?.data || []);
|
||
|
|
} catch (err) {
|
||
|
|
console.error("Error fetching articles:", err);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
fetchArticles();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<section className="px-4 py-8 bg-white">
|
||
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-1 max-w-[1350px] mx-auto">
|
||
|
|
{articles.map((article) => {
|
||
|
|
const imageUrl =
|
||
|
|
article.thumbnailUrl ||
|
||
|
|
article.files?.[0]?.fileUrl ||
|
||
|
|
"/placeholder.jpg"; // fallback jika gambar tidak ada
|
||
|
|
|
||
|
|
const category =
|
||
|
|
article.categoryName ||
|
||
|
|
article.categories?.[0]?.title ||
|
||
|
|
"SUARA WARGA";
|
||
|
|
|
||
|
|
// Format tanggal dari createdAt
|
||
|
|
const date = new Date(article.createdAt).toLocaleDateString("id-ID", {
|
||
|
|
day: "numeric",
|
||
|
|
month: "long",
|
||
|
|
year: "numeric",
|
||
|
|
});
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div key={article.id}>
|
||
|
|
<Link
|
||
|
|
className="border border-gray-200 overflow-hidden shadow-sm bg-white h-[440px]"
|
||
|
|
href={`/detail/${article?.id}`}
|
||
|
|
>
|
||
|
|
<Image
|
||
|
|
src={imageUrl}
|
||
|
|
alt={article.title}
|
||
|
|
width={267}
|
||
|
|
height={191}
|
||
|
|
className="w-full h-48 object-cover"
|
||
|
|
/>
|
||
|
|
<div className="p-4 text-center">
|
||
|
|
<p className="text-xs text-gray-400 font-medium tracking-wider uppercase py-2">
|
||
|
|
{category}
|
||
|
|
</p>
|
||
|
|
<h3 className="text-lg font-semibold text-gray-900 mb-4 leading-snug px-9">
|
||
|
|
{article.title}
|
||
|
|
</h3>
|
||
|
|
<p className="text-xs text-gray-400">{date}</p>
|
||
|
|
</div>
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
}
|