web-mikul-news/components/landing-page/news.tsx

285 lines
9.3 KiB
TypeScript
Raw Normal View History

2025-07-02 15:44:00 +00:00
"use client";
2025-10-12 15:09:52 +00:00
import { getAdvertise } from "@/service/advertisement";
2025-07-02 15:44:00 +00:00
import { getListArticle } from "@/service/article";
import { Clock } from "lucide-react";
import Image from "next/image";
2025-09-02 03:22:35 +00:00
import Link from "next/link";
2025-07-02 15:44:00 +00:00
import { useEffect, useState } from "react";
type postsData = {
id: number;
title: string;
description: string;
categoryName: string;
createdAt: string;
createdByName: string;
2025-10-12 15:09:52 +00:00
customCreatorName: string;
2025-07-02 15:44:00 +00:00
thumbnailUrl: string;
categories: {
title: string;
}[];
files: {
2025-09-24 09:01:07 +00:00
fileUrl: string;
2025-07-02 15:44:00 +00:00
file_alt: string;
}[];
};
2025-10-12 15:09:52 +00:00
type Advertise = {
id: number;
title: string;
description: string;
placement: string;
contentFileUrl: string;
redirectLink: string;
};
2025-07-02 15:44:00 +00:00
export default function Beranda() {
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [posts, setPosts] = useState<postsData[]>([]);
2025-09-17 06:24:41 +00:00
const [showData, setShowData] = useState("100");
2025-07-02 15:44:00 +00:00
const [search, setSearch] = useState("");
const [selectedCategories, setSelectedCategories] = useState<any>("");
const [startDateValue, setStartDateValue] = useState({
startDate: null,
endDate: null,
});
2025-10-12 15:09:52 +00:00
const [bannerAd, setBannerAd] = useState<Advertise | null>(null);
useEffect(() => {
initStateAdver();
}, []);
async function initStateAdver() {
const req = {
limit: 100,
page: 1,
sort: "desc",
sortBy: "created_at",
isPublish: true,
};
try {
const res = await getAdvertise(req);
const data: Advertise[] = res?.data?.data || [1];
// filter iklan dengan placement = "banner"
const banner = data.find((ad) => ad.placement === "banner");
if (banner) {
setBannerAd(banner);
}
} catch (err) {
console.error("Error fetching advertisement:", err);
}
}
2025-07-02 15:44:00 +00:00
useEffect(() => {
initState();
}, [page, showData, startDateValue, selectedCategories]);
async function initState() {
// loading();
const req = {
limit: showData,
page,
search,
categorySlug: Array.from(selectedCategories).join(","),
sort: "desc",
2025-08-19 05:33:21 +00:00
isPublish: true,
2025-07-02 15:44:00 +00:00
sortBy: "created_at",
};
try {
const res = await getListArticle(req);
setPosts(res?.data?.data || []);
setTotalPage(res?.data?.meta?.totalPage || 1);
} finally {
2025-07-03 02:03:07 +00:00
// close();
2025-07-02 15:44:00 +00:00
}
}
return (
<section className="max-w-7xl mx-auto px-10 py-5 bg-white">
<div className="flex flex-col md:flex-row md:items-center md:justify-between mb-8 pb-1 gap-2 bg-white border-b-2 pt-2 ">
2025-09-02 03:22:35 +00:00
<h2 className="text-sm font-bold">Pembangunan</h2>
2025-07-02 15:44:00 +00:00
<div className="flex flex-wrap gap-2 text-xs text-gray-600">
2025-09-17 06:24:41 +00:00
<Link href={"/category/development"}>
<button className="hover:text-green-500">ALL</button>
</Link>
<button className="hover:text-green-500 text-green-500">
Pembangunan
</button>
2025-07-02 15:44:00 +00:00
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-10 pt-4 ">
2025-09-17 06:24:41 +00:00
{posts
.filter((post) =>
post.categories?.some(
(category) => category.title.toLowerCase() === "pembangunan"
)
)
.slice(0, 6) // Ambil 4 artikel pertama setelah difilter
.map((post, index) => (
<div key={index} className="bg-white overflow-hidden">
<Link href={`/detail/${post?.id}`}>
<div className="relative">
<Image
src={
post.thumbnailUrl ||
2025-09-24 09:01:07 +00:00
post?.files?.[0]?.fileUrl ||
2025-09-17 06:24:41 +00:00
"/default-image.jpg"
}
alt={post.title}
width={500}
height={300}
className="w-full h-52 md:h-56 object-cover"
/>
<div className="absolute inset-0 bg-black/20" />
<span className="absolute top-1 left-1 bg-[#FFC600] text-black text-[11px] px-2 py-1 uppercase">
{post.categories?.[0]?.title}
</span>
<div className="p-3 md:p-2 absolute bottom-1 left-1 text-white">
<h3 className="font-bold text-sm md:text-base leading-snug mb-1">
{post.title}
</h3>
2025-07-02 15:44:00 +00:00
2025-09-17 06:24:41 +00:00
<div className="text-xs flex items-center gap-2">
<Clock className="w-3 h-3" />
<span>
2025-10-12 15:09:52 +00:00
{post?.customCreatorName || post.createdByName} -{" "}
2025-09-17 06:24:41 +00:00
{new Date(post.createdAt).toLocaleDateString("id-ID", {
day: "numeric",
month: "long",
year: "numeric",
})}
</span>
</div>
2025-09-02 03:22:35 +00:00
</div>
2025-07-02 15:44:00 +00:00
</div>
2025-09-17 06:24:41 +00:00
</Link>
</div>
))}
</div>
2025-10-12 15:09:52 +00:00
<div className="relative mt-10 mb-2 flex justify-center mx-8 border my-8 h-[350px] overflow-hidden bg-white">
{bannerAd ? (
<a
href={bannerAd.redirectLink}
target="_blank"
rel="noopener noreferrer"
className="block w-full"
>
<div className="relative w-full h-[350px] flex justify-center">
<Image
src={bannerAd.contentFileUrl}
alt={bannerAd.title || "Iklan Banner"}
width={1200} // ukuran dasar untuk responsive
height={350}
className="object-cover w-full h-full"
/>
</div>
</a>
) : (
<Image
src="/image-kolom.png"
alt="Berita Utama"
width={1200}
height={188}
className="object-contain w-full h-[188px]"
/>
)}
2025-09-17 06:24:41 +00:00
</div>
<div className="flex flex-col md:flex-row md:items-center md:justify-between mb-8 pb-1 gap-2 bg-white border-b-2 pt-2 ">
<h2 className="text-sm font-bold">Kesehatan</h2>
<div className="flex flex-wrap gap-2 text-xs text-gray-600">
<Link href={"/category/health"}>
<button className="hover:text-green-500">ALL</button>
</Link>
<button className="hover:text-green-500 text-green-500">
Kesehatan
</button>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-10 pt-4 ">
{posts
.filter((post) =>
post.categories?.some(
(category) => category.title.toLowerCase() === "kesehatan"
)
)
.slice(0, 6) // Ambil 4 artikel pertama setelah difilter
.map((post, index) => (
<div key={index} className="bg-white overflow-hidden">
<Link href={`/detail/${post?.id}`}>
<div className="relative">
<Image
src={
post.thumbnailUrl ||
2025-09-24 09:01:07 +00:00
post?.files?.[0]?.fileUrl ||
2025-09-17 06:24:41 +00:00
"/default-image.jpg"
}
alt={post.title}
width={500}
height={300}
className="w-full h-52 md:h-56 object-cover"
/>
<div className="absolute inset-0 bg-black/20" />
<span className="absolute top-1 left-1 bg-[#FFC600] text-black text-[11px] px-2 py-1 uppercase">
{post.categories?.[0]?.title}
</span>
<div className="p-3 md:p-2 absolute bottom-1 left-1 text-white">
<h3 className="font-bold text-sm md:text-base leading-snug mb-1">
{post.title}
</h3>
<div className="text-xs flex items-center gap-2">
<Clock className="w-3 h-3" />
<span>
2025-10-12 15:09:52 +00:00
{post?.customCreatorName || post.createdByName} -{" "}
2025-09-17 06:24:41 +00:00
{new Date(post.createdAt).toLocaleDateString("id-ID", {
day: "numeric",
month: "long",
year: "numeric",
})}
</span>
</div>
</div>
</div>
</Link>
</div>
))}
2025-07-02 15:44:00 +00:00
</div>
2025-10-12 15:09:52 +00:00
<div className="relative mt-10 mb-2 flex justify-center mx-8 border my-8 h-[350px] overflow-hidden bg-white">
{bannerAd ? (
<a
href={bannerAd.redirectLink}
target="_blank"
rel="noopener noreferrer"
className="block w-full"
>
<div className="relative w-full h-[350px] flex justify-center">
<Image
src={bannerAd.contentFileUrl}
alt={bannerAd.title || "Iklan Banner"}
width={1200} // ukuran dasar untuk responsive
height={350}
className="object-cover w-full h-full"
/>
</div>
</a>
) : (
<Image
src="/image-kolom.png"
alt="Berita Utama"
width={1200}
height={188}
className="object-contain w-full h-[188px]"
/>
)}
2025-07-02 15:44:00 +00:00
</div>
</section>
);
}