web-arah-negeri/components/landing-page/latest-news.tsx

181 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { getListArticle } from "@/service/article";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
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 News() {
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [articles, setArticles] = useState<Article[]>([]);
const [showData, setShowData] = useState("6");
const [search] = useState("");
const [selectedCategories] = useState<any>("");
const [startDateValue] = useState({
startDate: null,
endDate: null,
});
// Fetch data setiap kali page berubah
useEffect(() => {
initState();
}, [page, showData, startDateValue, selectedCategories]);
async function initState() {
const req = {
limit: showData,
page,
search,
categorySlug: Array.from(selectedCategories).join(","),
sort: "desc",
isPublish: true,
sortBy: "created_at",
};
try {
const res = await getListArticle(req);
setArticles(res?.data?.data || []);
setTotalPage(res?.data?.meta?.totalPage || 1);
} catch (err) {
console.error("Error fetching articles:", err);
}
}
const handlePrev = () => {
if (page > 1) setPage((prev) => prev - 1);
};
const handleNext = () => {
if (page < totalPage) setPage((prev) => prev + 1);
};
return (
<section className="max-w-screen-xl mx-auto px-4 py-10">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Berita Terbaru */}
<div className="lg:col-span-2">
<div className="flex flex-row items-center gap-2 mb-4">
<h2 className="text-lg font-semibold">Berita Terbaru</h2>
<div className="flex-grow border-t-2 border-gray-300 rounded-md" />
</div>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{articles.length > 0 ? (
articles.map((item) => (
<div key={item.id} className="group cursor-pointer">
<Link href={`/detail/${item.id}`}>
<div className="relative w-full aspect-[3/2] overflow-hidden">
<Image
src={
item.thumbnailUrl ||
item.files?.[0]?.fileUrl ||
"/placeholder.jpg"
}
alt={item.files?.[0]?.file_alt || item.title}
fill
className="object-cover w-full h-full group-hover:scale-105 transition-transform duration-300"
/>
<span className="absolute bottom-2 left-2 bg-yellow-400 text-black text-[10px] px-2 py-1">
{item.categoryName ||
item.categories?.[0]?.title ||
"Umum"}
</span>
</div>
<h3 className="mt-3 font-bold leading-snug line-clamp-2">
{item.title}
</h3>
<p className="text-xs text-[#A0A0A0] mt-1 flex items-center gap-1">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
className="text-gray-400"
>
<path
fill="currentColor"
d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m0 2a1 1 0 0 1 .993.883L13 7v4.586l2.707 2.707a1 1 0 0 1-1.32 1.497l-.094-.083l-3-3a1 1 0 0 1-.284-.576L11 12V7a1 1 0 0 1 1-1"
/>
</svg>
{new Date(item.createdAt).toLocaleDateString("id-ID", {
day: "2-digit",
month: "long",
year: "numeric",
})}
</p>
</Link>
</div>
))
) : (
<p className="col-span-3 text-center text-gray-500">
Tidak ada artikel tersedia.
</p>
)}
</div>
{/* Pagination */}
<div className="mt-8 flex flex-wrap gap-2 justify-start">
<button
onClick={handlePrev}
disabled={page === 1}
className={`border px-3 py-1 text-xs rounded-sm ${
page === 1
? "opacity-50 cursor-not-allowed"
: "hover:bg-gray-100"
}`}
>
PREV
</button>
<button
onClick={handleNext}
disabled={page >= totalPage}
className={`border px-3 py-1 text-xs rounded-sm ${
page >= totalPage
? "opacity-50 cursor-not-allowed"
: "hover:bg-gray-100"
}`}
>
NEXT
</button>
</div>
</div>
{/* Twitter Section */}
<div>
<h3 className="text-xl font-semibold border-b-2 border-gray-300 mb-4">
Twitter @ArahNegeri
</h3>
{/* Embed atau konten lain */}
</div>
</div>
{/* Banner bawah */}
<div className="relative my-5 h-[188px] overflow-hidden flex items-center mx-auto border">
<Image
src="/image-kolom.png"
alt="Berita Utama"
fill
className="object-contain"
/>
</div>
</section>
);
}