web-milenial-bersuara/components/landing-page/travel-news.tsx

145 lines
5.0 KiB
TypeScript
Raw Normal View History

2025-10-06 06:21:08 +00:00
"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;
thumbnailUrl: string;
categories: {
title: string;
}[];
files: {
file_url: string;
file_alt: string;
}[];
};
const TravelNews = () => {
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [articles, setArticles] = useState<Article[]>([]);
const [showData, setShowData] = useState("4");
const [search, setSearch] = useState("");
const [selectedCategories, setSelectedCategories] = useState<any>([]);
const [startDateValue, setStartDateValue] = useState({
startDate: null,
endDate: null,
});
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);
}
}
return (
<section className="bg-white">
<div className="relative py-16 px-4 md:px-20">
<div
className="absolute inset-0 bg-cover bg-center z-0 opacity-90 h-[660px]"
style={{ backgroundImage: "url('/travel.jpg')" }}
/>
<div className="relative z-10 pt-48">
<h2 className="text-4xl font-bold text-white text-start mb-4">
Travel News
</h2>
<p className="text-white text-start mb-12 text-lg">
Find your best tour and start the adventure at the lowest budget and
best experiences
</p>
{/* Top Featured News */}
<div className="grid md:grid-cols-3 gap-6">
{/* CARD 1 */}
{articles.slice(0, 3).map((item) => (
<div key={item.id}>
<Link
className="relative rounded-md overflow-hidden shadow-lg"
href={`/detail/${item?.id}`}
>
<Image
src={item.thumbnailUrl || "/placeholder.jpg"}
alt={item.title}
width={600}
height={400}
className="w-full h-64 object-cover group-hover:scale-105 transition-transform duration-500"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent p-4 flex flex-col justify-end">
<h3 className="text-white text-lg font-semibold leading-snug">
{item.title}
</h3>
<p className="text-white text-sm mt-2">
{new Date(item.createdAt).toLocaleDateString("id-ID", {
day: "2-digit",
month: "long",
year: "numeric",
})}
</p>
</div>
</Link>
</div>
))}
</div>
{/* Bottom News List */}
</div>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-4 text-sm max-w-7xl mx-auto mb-10">
{[
"Your Guide to Canggus Hottest Street: The Essential Batu Bolong",
"Expert Tips: How To Become A Professional Travel Blogger",
"Important things you should know for Mount Agung hiking",
"How to build a freelance career while traveling the world",
"Bali Nightlife Guide : The most popular clubs in Kuta",
"This English breakfast pie is maybe the most British thing ever",
"Everything You Need to Know About Solo Travel",
"10 things you didnt know about being solo traveler in Asia",
"Kehadiran Media Hub Polri Jadi Jawaban atas Kebutuhan Jurnalis Masa Kini",
"Indonesia Tersingkir dari Piala Asia U-17 2025 Setelah Kalah Telak 6-0 dari Korea Utara",
"Tayang Besok, Gen 99 Hospital Playlist Juga Jadi Cameo di Resident Playbook",
"Tak Perpanjang Kontrak, Megawati Hengkang dari Red Sparks",
].map((item, idx) => (
<div key={idx} className="flex items-start gap-2">
<span className="text-teal-500"></span>
<p>{item}</p>
</div>
))}
</div>
<div className="max-w-7xl relative my-5 h-[125px] overflow-hidden flex items-center mx-auto border">
<Image
src="/image-kolom.png"
alt="Berita Utama"
fill
className="object-cover"
/>
</div>
</section>
);
};
export default TravelNews;