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

536 lines
22 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 { useEffect, useState } from "react";
const data1 = {
main: {
image: "/stadion.png",
category: "BERANDA",
title:
"Deretan Stadion Terbesar di ASEAN, Kebanggaan Negara-Negara Asia Tenggara",
author: "SALMA HN",
date: "24 MARET 2025",
comments: 0,
excerpt:
"KAKORLANTAS POLRI, Cilegon. Kakorlantas Polri Irjen Pol Drs. Agus Suryonogroho S.H, M.Hum bersama Menteri Perhubungan (Menhub) Dudy Purwagandhi meninjau kondisi...",
},
left: [
{
image: "/menkes.jpg",
category: "BERANDA",
title:
"Menkes: Kecelakaan Lalu Lintas Turun 45%, Apresiasi Seluruh Stakeholder",
author: "SALMA HN",
date: "10 MARET 2025",
comments: 0,
excerpt:
"Jakarta - Rekrutmen Bersama BUMN (RBB BUMN) 2025 kini resmi dibuka mulai hari ini...",
},
{
image: "/kakorlantas.jpg",
category: "BERANDA",
title:
"Korlantas Polri: One Way Lokal dan Contraflow untuk Kelancaran Arus Balik",
author: "SALMA HN",
date: "7 MARET 2025",
comments: 0,
excerpt:
"JAKARTA - Program Rekrutmen Bersama BUMN (RBB) 2025 resmi dibuka pada Jumat...",
},
],
topRight: [
{
image: "/bimantoro.png",
category: "BERANDA",
title:
"Bimantoro Wiyono Apresiasi Keberhasilan Atur Mudik dan Arus Balik Lebaran 2025",
author: "SALMA HN",
date: "10 MARET 2025",
comments: 0,
excerpt:
"Jakarta - Rekrutmen Bersama BUMN (RBB BUMN) 2025 kini resmi dibuka mulai hari ini, Senin, 10 Maret 2025. Pelamar yang...",
},
],
topRightMain: [
{
image: "/bimantoro.png",
category: "BERANDA",
title:
"Bimantoro Wiyono Apresiasi Keberhasilan Atur Mudik dan Arus Balik Lebaran 2025",
author: "SALMA HN",
date: "10 MARET 2025",
comments: 0,
excerpt:
"Jakarta - Rekrutmen Bersama BUMN (RBB BUMN) 2025 kini resmi dibuka mulai hari ini, Senin, 10 Maret 2025. Pelamar yang...",
},
{
image: "/cpns.jpg",
category: "BERANDA",
title:
"Polri Dapat Meningkatkan Transparansi: Paparan Fathul Ulum tentang Keterbukaan Informasi",
author: "SALMA HN",
date: "7 MARET 2025",
comments: 0,
excerpt:
"JAKARTA - Program Rekrutmen Bersama BUMN (RBB) 2025 resmi dibuka pada Jumat...",
},
{
image: "/bpnt.jpg",
category: "BERANDA",
title: "Tutorial Cek Status Penerima BPNT 2025 Melalui HP",
author: "SALMA HN",
date: "7 MARET 2025",
comments: 0,
excerpt:
"JAKARTA - Program Rekrutmen Bersama BUMN (RBB) 2025 resmi dibuka pada Jumat...",
},
],
bottomMid: [
{
image: "/vvip.jpg",
title:
"Pembangunan Bandara VVIP IKN Berjalan Lancar, Ditargetkan Rampung Maret 2025",
date: "6 MARET 2025",
},
{
image: "/pmk.png",
title: "PMK 11/2025 Ubah Ketentuan PPN Besaran Tertentu, Ini Rinciannya",
date: "11 FEBRUARI 2025",
},
{
image: "/cpns.jpg",
title:
"Hasil Kelulusan CPNS 2024 Diumumkan, Simak Arti Kode dan Cara Mengecek Hasilnya",
date: "17 FEBRUARI 2025",
},
],
bottomRight: [
{
image: "/kapolri.jpg",
title:
"Kapolri dan Kakorlantas Pantau Arus Balik di KM 456 Salatiga, Pastikan Arus Balik Aman",
date: "6 MARET 2025",
},
{
image: "/timnas.png",
title:
"Menang atas Bahrain, Indonesia Masih Harus Waspada Ancaman China dan Jepang",
date: "11 FEBRUARI 2025",
},
],
};
// Disusun ulang agar cocok dengan struktur komponen
const data = {
leftMain: data1.main,
leftList: data1.left,
centerMain: data1.topRight[0],
centerList: data1.bottomMid.slice(0, 3),
rightMain: data1.topRightMain[0],
rightList: data1.bottomRight.slice(0, 3),
};
const popularPosts = [
{
id: 1,
image: "/investasi.jpg",
category: "BERANDA",
title:
"Polda Gorontalo buka layanan Aduan Pinjaman Online dan Investasi Ilegal",
excerpt:
"Jakarta Banyaknya korban pinjaman Online yang terjadi akhir-akhir ini, membuat Kapolda Gorontalo Irjen Pol....",
author: "SALMA HASNA",
date: "25 MARET 2025",
comments: 0,
},
{
id: 2,
image: "/kkb.jpg",
category: "BERANDA",
title: "Mematahkan Kelompok Kriminal Bersenjata (KKB) di Papua",
excerpt:
"Penanganan keamanan di Papua harus dilakukan hati-hati karena di Papua merupakan kombinasi antara kepentingan ideologis...",
author: "SALMA HASNA",
date: "24 MARET 2025",
comments: 0,
},
{
id: 3,
image: "/mural.jpg",
category: "BERANDA",
title: "Polri Gelar Lomba Safari Bhayangkara Mural",
excerpt:
"JAKARTA - PolrI bersama mitra kembali menggelar lomba mural jilid kedua yang diberi nama Safari...",
author: "SALMA HASNA",
date: "25 MARET 2025",
comments: 0,
},
];
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;
}[];
};
export default function Latest() {
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [articles, setArticles] = useState<Article[]>([]);
const [popularPosts, setPopularPosts] = useState<Article[]>([]);
const [showData, setShowData] = useState("5");
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() {
// loading();
const req = {
limit: showData,
page,
search,
categorySlug: Array.from(selectedCategories).join(","),
sort: "desc",
sortBy: "created_at",
};
try {
const res = await getListArticle(req);
setArticles(res?.data?.data || []);
setTotalPage(res?.data?.meta?.totalPage || 1);
setPopularPosts(res?.data?.data || []);
} finally {
// close();
}
}
return (
<section className="bg-white py-10 px-4 md:px-10 w-full">
<div className="max-w-screen-6xl mx-auto flex flex-col lg:flex-row lg:justify-between gap-5">
<div className="w-full lg:w-[750px]">
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
FEATURED
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 ">
<div className=" w-full">
<div className="relative w-full aspect-video mb-5">
<Image
src={
articles[0]?.files?.[0]?.file_url || "/default-image.jpg"
}
alt={"articles[0]?.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover"
/>
<div className="absolute inset-0 bg-black/20" />
<div className="absolute bottom-0.5 left-2 text-white">
<h3 className=" font-semibold text-base mb-1">
{articles[0]?.title}
</h3>
<p className=" text-xs mb-2 flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<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"
/>
</g>
</svg>{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
<div className="space-y-5">
{articles.slice(1, 5).map((article, index) => (
<div key={index} className="flex gap-3">
<div className="relative w-[120px] h-[86px] shrink-0">
<Image
src={article?.thumbnailUrl}
alt={"article?.title"}
fill
className="object-cover"
/>
</div>
<div>
<h4 className="text-sm font-semibold mb-3">
{article.title}
</h4>
<p className="text-xs text-gray-500 flex gap-2 articles-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<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"
/>
</g>
</svg>{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
))}
</div>
</div>
<div className="w-full">
<div className="relative w-full aspect-video mb-5">
<Image
src={
articles[0]?.files?.[0]?.file_url || "/default-image.jpg"
}
alt={"articles[0]?.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover "
/>
<div className="absolute inset-0 bg-black/20" />
<div className="absolute bottom-0.5 left-2 text-white">
<h3 className=" font-semibold text-base mb-1">
{articles[0]?.title}
</h3>
<p className=" text-xs mb-2 flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<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"
/>
</g>
</svg>{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
<div className="space-y-5">
{articles.slice(1, 5).map((article, index) => (
<div key={index} className="flex gap-3">
<div className="relative w-[120px] h-[86px] shrink-0">
<Image
src={article?.thumbnailUrl}
alt={"article?.title"}
fill
className="object-cover "
/>
</div>
<div>
<h4 className="text-sm font-semibold mb-3">
{article?.title}
</h4>
<p className="text-xs text-gray-500 flex gap-2 articles-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<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"
/>
</g>
</svg>{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
))}
</div>
</div>
</div>
<div className="relative my-5 max-w-full h-[125px] overflow-hidden flex items-center mx-auto border">
<Image
src="/image-kolom.png"
alt="Berita Utama"
fill
className="object-cover"
/>
</div>
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
BasketBall
</h2>
<div className="w-full border bg-[#FAFAFA] h-[64px] flex justify-center items-center">
<p className="text-center ">No Content Available</p>
</div>
<div className="relative my-5 max-w-full h-[125px] overflow-hidden flex items-center mx-auto border">
<Image
src="/image-kolom.png"
alt="Berita Utama"
fill
className="object-cover"
/>
</div>
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
Late News
</h2>
<div className="w-full border bg-[#FAFAFA] h-[64px] flex justify-center items-center">
<p className="text-center ">No Content Available</p>
</div>
</div>
<aside className="w-full lg:w-[345px]">
<div className="">
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
RECOMMENDED
</h2>
<div className="space-y-8">
{popularPosts.slice(1, 5).map((post, index) => (
<div key={index} className="space-y-3">
<div
className={`flex gap-4 ${
post.files?.[0]?.file_url
? "flex-col md:flex-row"
: "flex-col"
}`}
>
<div className="flex-1">
<h3 className="text-base sm:text-lg md:text-sm font-bold leading-tight">
{post?.title}
</h3>
<div className="text-xs mt-1.5 text-[#A0A0A0] space-x-2 flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<g fill="none">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<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"
/>
</g>
</svg>{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
/>
</svg>{" "}
0
</div>
</div>
{post.thumbnailUrl && (
<div className="w-full md:w-1/3 relative">
<div className="w-full aspect-[4/3] sm:w-[260px] sm:h-[157px] md:max-w-[320px] md:h-[220px] lg:max-w-[120px] lg:h-[87px] relative ml-auto">
<Image
src={post?.thumbnailUrl}
alt={"post?.title"}
fill
className="object-cover rounded"
/>
</div>
</div>
)}
</div>
<p className="text-[13px] text-[#3D4248] line-clamp-2 mb-3">
{post.description}
</p>
</div>
))}
</div>
</div>
<div className="relative w-[1111px] max-w-full h-[300px] overflow-hidden flex items-center mx-auto border my-6 rounded">
<Image
src="/kolom.png"
alt="Berita Utama"
fill
className="object-contain rounded"
/>
</div>
</aside>
</div>
</section>
);
}