131 lines
4.2 KiB
TypeScript
131 lines
4.2 KiB
TypeScript
|
|
"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 Header() {
|
||
|
|
const [articles, setArticles] = useState<Article[]>([]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const fetchArticles = async () => {
|
||
|
|
try {
|
||
|
|
const req = {
|
||
|
|
limit: "2",
|
||
|
|
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="max-w-7xl mx-auto bg-white">
|
||
|
|
{/* Header Banner */}
|
||
|
|
<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>
|
||
|
|
|
||
|
|
<p className="text-xl font-serif font-semibold border-b-2 my-6 mx-4">
|
||
|
|
BERITA UTAMA
|
||
|
|
</p>
|
||
|
|
|
||
|
|
{/* Grid Artikel */}
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 max-w-screen-xl mx-auto px-4">
|
||
|
|
{articles.length > 0 ? (
|
||
|
|
articles.map((item, index) => (
|
||
|
|
<div key={item.id} className="relative h-[410px] w-full">
|
||
|
|
<Link href={`/detail/${item.id}`}>
|
||
|
|
<Image
|
||
|
|
src={
|
||
|
|
item.thumbnailUrl ||
|
||
|
|
item.files?.[0]?.fileUrl ||
|
||
|
|
"/placeholder.jpg"
|
||
|
|
}
|
||
|
|
alt={item.files?.[0]?.file_alt || item.title}
|
||
|
|
fill
|
||
|
|
className="object-cover rounded-md"
|
||
|
|
/>
|
||
|
|
|
||
|
|
{/* Overlay gradient */}
|
||
|
|
<div
|
||
|
|
className={`absolute inset-0 ${
|
||
|
|
index % 2 === 0
|
||
|
|
? "bg-gradient-to-r from-indigo-900/80 to-red-500/60"
|
||
|
|
: "bg-gradient-to-r from-green-900/80 to-yellow-500/60"
|
||
|
|
}`}
|
||
|
|
/>
|
||
|
|
|
||
|
|
{/* Text content */}
|
||
|
|
<div className="absolute inset-0 flex flex-col items-center justify-center text-center text-white px-4 z-20">
|
||
|
|
<span className="text-[10px] bg-yellow-400 text-black px-2 py-1 mb-3 uppercase">
|
||
|
|
{item.categoryName ||
|
||
|
|
item.categories?.[0]?.title ||
|
||
|
|
"Berita"}
|
||
|
|
</span>
|
||
|
|
<h2 className="text-xl md:text-2xl font-semibold leading-snug w-7/12">
|
||
|
|
{item.title}
|
||
|
|
</h2>
|
||
|
|
<div className="flex flex-row items-center mt-2">
|
||
|
|
<svg
|
||
|
|
xmlns="http://www.w3.org/2000/svg"
|
||
|
|
width="16"
|
||
|
|
height="16"
|
||
|
|
viewBox="0 0 24 24"
|
||
|
|
fill="currentColor"
|
||
|
|
className="mr-1"
|
||
|
|
>
|
||
|
|
<path d="M12 1.75a10.25 10.25 0 1 0 0 20.5a10.25 10.25 0 0 0 0-20.5Zm0 1.5a8.75 8.75 0 1 1 0 17.5a8.75 8.75 0 0 1 0-17.5Zm.75 4a.75.75 0 0 0-1.5 0v5.25a.75.75 0 0 0 .313.613l3 2.25a.75.75 0 0 0 .874-1.222l-2.687-2.016V7.25Z" />
|
||
|
|
</svg>
|
||
|
|
<p className="text-xs text-white">
|
||
|
|
{new Date(item.createdAt).toLocaleDateString("id-ID", {
|
||
|
|
day: "2-digit",
|
||
|
|
month: "long",
|
||
|
|
year: "numeric",
|
||
|
|
})}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
))
|
||
|
|
) : (
|
||
|
|
<p className="text-center col-span-2 text-gray-500">
|
||
|
|
Tidak ada artikel tersedia.
|
||
|
|
</p>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
);
|
||
|
|
}
|