first commit

This commit is contained in:
Anang Yusman 2025-07-03 10:03:07 +08:00
parent 074a3ce9c7
commit b449cab9dd
9 changed files with 1040 additions and 253 deletions

30
app/detail/[id]/page.tsx Normal file
View File

@ -0,0 +1,30 @@
import DetailContent from "@/components/details/details-content";
import Footer from "@/components/landing-page/footer";
import Navbar from "@/components/landing-page/navbar";
import Image from "next/image";
export default function Home() {
return (
<div className="relative min-h-screen font-[family-name:var(--font-geist-sans)]">
<div className="fixed top-0 left-0 w-full h-auto z-0">
<Image
src="/rumput.jpg"
alt="Background"
width={1450}
height={600}
className="w-full h-auto object-cover"
priority
/>
</div>
<div className="relative z-10 bg-[#F2F4F3] max-w-7xl mx-auto">
<Navbar />
<div className="flex-1">
<DetailContent />
</div>
<Footer />
</div>
</div>
);
}

33
app/popular/page.tsx Normal file
View File

@ -0,0 +1,33 @@
import Author from "@/components/landing-page/author";
import Footer from "@/components/landing-page/footer";
import Header from "@/components/landing-page/header";
import Latest from "@/components/landing-page/latest";
import LatestandPopular from "@/components/landing-page/latest-and-popular";
import Navbar from "@/components/landing-page/navbar";
import News from "@/components/landing-page/news";
import Image from "next/image";
export default function Home() {
return (
<div className="relative min-h-screen font-[family-name:var(--font-geist-sans)]">
<div className="fixed top-0 left-0 w-full h-auto z-0">
<Image
src="/rumput.jpg"
alt="Background"
width={1450}
height={600}
className="w-full h-auto object-cover"
priority
/>
</div>
<div className="relative z-10 bg-[#F2F4F3] max-w-7xl mx-auto">
<Navbar />
<div className="flex-1">
<Header />
</div>
<Footer />
</div>
</div>
);
}

View File

@ -0,0 +1,622 @@
"use client";
import Image from "next/image";
import Author from "../landing-page/author";
import { useEffect, useState } from "react";
import Link from "next/link";
import { getListArticle } from "@/service/article";
import { close } from "@/config/swal";
type TabKey = "trending" | "comments" | "latest";
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 DetailContent() {
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [articles, setArticles] = useState<Article[]>([]);
const [showData, setShowData] = useState("5");
const [search, setSearch] = useState("");
const [selectedCategories, setSelectedCategories] = useState<any>("");
const [startDateValue, setStartDateValue] = useState({
startDate: null,
endDate: null,
});
const [tabArticles, setTabArticles] = useState<Article[]>([]);
const [activeTab, setActiveTab] = useState<TabKey>("trending");
const tabs: { id: TabKey; label: string }[] = [
{ id: "trending", label: "Trending" },
{ id: "comments", label: "Comments" },
{ id: "latest", label: "Latest" },
];
useEffect(() => {
fetchTabArticles();
}, [activeTab]);
async function fetchTabArticles() {
const req = {
limit: "5",
page: 1,
search: "",
categorySlug: "",
sort: "desc",
sortBy: "created_at",
};
try {
if (activeTab === "trending") {
req.sortBy = "view_count";
} else if (activeTab === "comments") {
req.sortBy = "comment_count";
} else {
req.sortBy = "created_at";
}
const res = await getListArticle(req);
setTabArticles(res?.data?.data || []);
} catch (error) {
console.error("Failed fetching tab articles:", error);
}
}
const content: Record<
TabKey,
{ image: string; title: string; date: string }[]
> = {
trending: [
{
image: "/thumb1.png",
title:
"#StopBullyDiSekolah: Peran Positif Media Sosial dalam Mengatasi Bullying",
date: "22 FEBRUARI 2024",
},
{
image: "/thumb2.png",
title:
"Polri Gelar Lomba Orasi Unjuk Rasa dalam Rangka Hari HAM Sedunia Berhadiah Total Lebih dari Rp 150 juta!",
date: "29 NOVEMBER 2021",
},
{
image: "/thumb3.png",
title: "Tingkatkan Ibadah Sambut #RamadhanPenuhDamai",
date: "7 MARET 2024",
},
{
image: "/thumb4.png",
title:
"Exploring the Charm of Papuas Traditional Clothing: A Captivating and Meaningful Cultural Heritage",
date: "1 AGUSTUS 2024",
},
],
comments: [
{
image: "/thumb-comment.png",
title: "Pengunjung Komentar Positif tentang Fitur Baru",
date: "3 JUNI 2024",
},
],
latest: [
{
image: "/thumb-latest.png",
title: "Update Terbaru dari Redaksi Hari Ini",
date: "2 JULI 2025",
},
],
};
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);
} finally {
// close();
}
}
return (
<>
<div className="flex items-center bg-[#F2F4F3] w-full overflow-hidden mb-4 py-6 px-8">
<Image
src="/mikul.png"
alt="Background"
width={272}
height={90}
className="w-full md:w-[272px] h-[90px] object-cover border"
priority
/>
</div>
<div className="bg-white grid grid-cols-1 md:grid-cols-3 gap-6 px-8 py-8">
<div className="md:col-span-2">
<p className="text-sm text-gray-500 mb-2">Home &gt; Internasional</p>
<h1 className="text-3xl md:text-4xl font-bold text-[#1a1a1a] leading-tight mb-4">
Bom Bunuh Diri Guncang Gereja di Damaskus, 20 Orang Tewas dan
Puluhan Terluka
</h1>
<div className="flex items-center space-x-2 text-sm text-gray-500 mb-4">
<Image
src="/author.png"
alt="author"
width={30}
height={30}
className="rounded-full"
/>
<span className="text-[#3ba6ed] font-medium">
christine natalia
</span>
<span></span>
<span>23 Juni 2025</span>
<span></span>
<span>Internasional</span>
</div>
<div className="w-full h-auto mb-6">
<Image
src="/bom.png"
alt="Berita"
width={800}
height={400}
className="rounded-lg w-full object-cover"
/>
<p className="text-sm text-gray-500 mt-2 text-end">
Bom Bunuh Diri Guncang Gereja di Damaskus, 20 Orang Tewas dan
Puluhan Terluka
</p>
</div>
<div className="flex relative">
<div className=" flex flex-col w-fit rounded overflow-hidden mr-5">
<Link
href="#"
aria-label="Facebook"
className="bg-[#3b5998] p-4 flex justify-center items-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="white"
viewBox="0 0 24 24"
>
<path d="M14 13.5h2.5l1-4H14v-2c0-1.03 0-2 2-2h1.5V2.14c-.326-.043-1.557-.14-2.857-.14C11.928 2 10 3.657 10 6.7v2.8H7v4h3V22h4z" />
</svg>
</Link>
<Link
href="#"
aria-label="Twitter"
className="bg-[#55acee] p-4 flex justify-center items-center"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="white"
viewBox="0 0 24 24"
>
<path d="M7.91 20.889c8.302 0 12.845-6.885 12.845-12.845c0-.193 0-.387-.009-.58A9.2 9.2 0 0 0 23 5.121a9.2 9.2 0 0 1-2.597.713a4.54 4.54 0 0 0 1.99-2.5a9 9 0 0 1-2.87 1.091A4.5 4.5 0 0 0 16.23 3a4.52 4.52 0 0 0-4.516 4.516c0 .352.044.696.114 1.03a12.82 12.82 0 0 1-9.305-4.718a4.526 4.526 0 0 0 1.4 6.03a4.6 4.6 0 0 1-2.043-.563v.061a4.524 4.524 0 0 0 3.62 4.428a4.4 4.4 0 0 1-1.189.159q-.435 0-.845-.08a4.51 4.51 0 0 0 4.217 3.135a9.05 9.05 0 0 1-5.608 1.936A9 9 0 0 1 1 18.873a12.84 12.84 0 0 0 6.91 2.016" />
</svg>
</Link>
<Link
href="#"
aria-label="Google"
className="bg-[#fce9e7] p-4 flex justify-center items-center text-white"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M7.796 14.333v-2.618h7.211c.066.382.12.763.12 1.265c0 4.364-2.923 7.462-7.33 7.462A7.63 7.63 0 0 1 .16 12.806a7.63 7.63 0 0 1 7.636-7.637c2.062 0 3.786.753 5.117 1.997L10.84 9.162c-.567-.546-1.56-1.178-3.044-1.178c-2.607 0-4.734 2.16-4.734 4.822s2.127 4.821 4.734 4.821c3.022 0 4.157-2.17 4.331-3.294zm13.27-2.6H23.2v2.134h-2.133V16h-2.134v-2.133H16.8v-2.134h2.133V9.6h2.134z" />
</svg>
</Link>
<Link
href="#"
aria-label="Share"
className="bg-[#cccccc] p-4 flex justify-center items-center text-white"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="m21 12l-7-7v4C7 10 4 15 3 20c2.5-3.5 6-5.1 11-5.1V19z" />
</svg>
</Link>
</div>
<div className="flex-1 overflow-y-auto">
<p className="text-gray-700 leading-relaxed text-justify">
Sebuah aksi bom bunuh diri terjadi di Gereja Saint Elias,
kawasan Dwelaa, Damaskus, Suriah, pada Minggu (22/6), menewaskan
sedikitnya 20 orang dan melukai 52 lainnya. Insiden tragis ini
terjadi saat gereja tengah dipenuhi jemaat, termasuk anak-anak
dan lansia, yang sedang mengikuti ibadah mingguan. Kementerian
Dalam Negeri Suriah mengonfirmasi bahwa pelaku serangan
merupakan anggota kelompok teroris ISIS. Dalam keterangan resmi,
pihak kementerian menyebut pelaku memasuki gereja dengan membawa
senjata api, melepaskan tembakan, dan kemudian meledakkan diri
dengan sabuk peledak yang dibawanya. Pasca ledakan, aparat
keamanan langsung mengamankan lokasi dan menutup akses ke area
sekitar untuk mencegah kemungkinan serangan susulan. Pihak
berwenang juga mengerahkan tim penyelamat dan tenaga medis untuk
mengevakuasi korban dan memberikan perawatan darurat kepada yang
terluka. Kementerian Kesehatan, melalui kantor berita SANA,
menginformasikan bahwa sebagian besar korban luka mengalami
cedera serius akibat serpihan ledakan. Sejumlah korban masih
dalam kondisi kritis dan dirawat di beberapa rumah sakit rujukan
di Damaskus. Seorang saksi mata bernama Lawrence Maamari
menuturkan bahwa pelaku masuk ke dalam gereja dengan senapan di
tangan. Jemaat yang panik sempat mencoba menghadang pelaku
sebelum akhirnya terjadi ledakan. Saksi lainnya, Ziad (40),
pemilik toko di dekat lokasi, mengatakan mendengar suara
tembakan disusul ledakan besar. Kami melihat kobaran api di
dalam gereja dan bangku-bangku terlempar ke arah pintu masuk,
ujarnya. Suasana mencekam sempat terjadi selama beberapa jam.
Beberapa warga kehilangan anggota keluarga dan berupaya
mencarinya di antara puing-puing bangunan serta rumah sakit
terdekat. Insiden ini menuai kecaman internasional. Utusan
Khusus PBB untuk Suriah, Geir Pedersen, menyebut aksi tersebut
sebagai kejahatan keji dan mendesak adanya penyelidikan
menyeluruh. Sementara itu, Kementerian Luar Negeri Prancis
menyatakan bahwa serangan ini merupakan bentuk terorisme brutal,
serta kembali menyuarakan pentingnya transisi damai di Suriah
agar seluruh warga dapat hidup dalam keamanan tanpa
diskriminasi. Pemerintah Suriah menilai serangan ini sebagai
langkah terdesak dari kelompok radikal untuk mengganggu
stabilitas nasional dan menciptakan ketegangan sektarian.
Menteri Dalam Negeri, Anas Khattab, menyampaikan belasungkawa
kepada keluarga korban dan menyatakan bahwa penyelidikan sudah
dimulai oleh tim khusus kementeriannya. Dalam keterangannya,
Khattab menegaskan bahwa aksi teror serupa tidak akan
menghentikan tekad pemerintah dalam menciptakan perdamaian. Ia
juga mengungkapkan bahwa kelompok ISIS kini menargetkan
komunitas-komunitas tertentu, termasuk umat Kristen dan Syiah,
dengan pola serangan yang lebih terorganisir. Beberapa minggu
sebelumnya, aparat keamanan berhasil menggagalkan sejumlah
rencana serangan dan menangkap sel-sel ISIS di wilayah Damaskus.
Operasi kontra-terorisme di Aleppo bahkan menewaskan tiga
anggota kelompok tersebut dan satu petugas keamanan. Insiden bom
bunuh diri di Damaskus menjadi pengingat bahwa ancaman
ekstremisme belum sepenuhnya sirna di Suriah. Pemerintah pun
terus berupaya meningkatkan keamanan dan memperkuat kerja sama
dengan pihak internasional dalam memberantas terorisme.
</p>
<Author />
<div className=" flex flex-row gap-2 items-center">
<span className="font-semibold text-sm text-gray-700">
Tags:
</span>
<div className="flex flex-wrap gap-2 mt-1">
{[
"Bom bunuh diri Suriah",
"Bom Damaskus",
"Gereja Saint Elias",
"Serangan ISIS",
].map((tag, index) => (
<span
key={index}
className="bg-gray-100 text-gray-700 text-sm px-2 py-1 rounded"
>
{tag}
</span>
))}
</div>
</div>
</div>
</div>
<div className="relative mb-2 h-[120px] overflow-hidden flex items-center border my-8">
<Image
src="/image-kolom.png"
alt="Berita Utama"
fill
className="object-contain"
/>
</div>
<div className="mt-10">
<div className="flex items-center space-x-4 p-4 border rounded-lg mb-6">
<Image
src="/author.png"
alt="Author"
width={60}
height={60}
className="rounded-full"
/>
<div>
<p className="text-green-600 font-bold text-lg">
christine natalia
</p>
</div>
</div>
<h2 className="text-2xl font-bold mb-2">Tinggalkan Balasan</h2>
<p className="text-gray-600 mb-4 text-sm">
Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib
ditandai <span className="text-green-600">*</span>
</p>
<form className="space-y-6 mt-6">
<div>
<label
htmlFor="komentar"
className="block text-sm font-medium mb-1"
>
Komentar <span className="text-green-600">*</span>
</label>
<textarea
id="komentar"
className="w-full border border-gray-300 rounded-md p-3 h-40 focus:outline-none focus:ring-2 focus:ring-green-600"
required
/>
</div>
<div>
<label
htmlFor="nama"
className="block text-sm font-medium mb-1"
>
Nama <span className="text-green-600">*</span>
</label>
<input
type="text"
id="nama"
className="w-full border border-gray-300 rounded-md p-2"
required
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label
htmlFor="email"
className="block text-sm font-medium mb-1"
>
Email <span className="text-green-600">*</span>
</label>
<input
type="email"
id="email"
className="w-full border border-gray-300 rounded-md p-2"
required
/>
</div>
<div>
<label
htmlFor="website"
className="block text-sm font-medium mb-1"
>
Situs Web
</label>
<input
type="url"
id="website"
className="w-full border border-gray-300 rounded-md p-2"
/>
</div>
</div>
<div className="flex items-start space-x-2 mt-2">
<input type="checkbox" id="saveInfo" className="mt-1" />
<label htmlFor="saveInfo" className="text-sm text-gray-700">
Simpan nama, email, dan situs web saya pada peramban ini untuk
komentar saya berikutnya.
</label>
</div>
<p className="text-red-600 text-sm">
The reCAPTCHA verification period has expired. Please reload the
page.
</p>
<button
type="submit"
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-6 py-2 rounded-md transition mt-2"
>
KIRIM KOMENTAR
</button>
</form>
</div>
</div>
<div className="md:col-span-1 space-y-6">
<div className="sticky top-0 space-y-6">
<div className="bg-white shadow p-4 rounded-lg">
<Image
src="/kolom.png"
alt="Iklan"
width={345}
height={345}
className="rounded"
/>
<button className="mt-4 w-full bg-black text-white py-2 rounded hover:opacity-90">
Learn More
</button>
</div>
<div className="bg-white shadow p-4 rounded-lg">
<h2 className="text-lg font-semibold mb-2">Connect with us</h2>
<div className="flex space-x-2">
<div className="bg-[#0057ff] text-white px-3 py-2 rounded">
<p className="text-sm font-bold"></p>
<p className="text-xs">139 Followers</p>
</div>
<div className="bg-[#ff0000] text-white px-3 py-2 rounded">
<p className="text-sm font-bold">YouTube</p>
<p className="text-xs">205k Subscribers</p>
</div>
<div className="bg-[#f9a825] text-white px-3 py-2 rounded">
<p className="text-sm font-bold">RSS</p>
<p className="text-xs">23.9k Followers</p>
</div>
</div>
</div>
<div className="bg-white shadow p-4 rounded-lg">
<div className="flex space-x-4 border-b mb-4">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`pb-2 text-sm font-medium ${
activeTab === tab.id
? "border-b-2 border-green-600 text-green-600"
: "text-gray-600"
}`}
>
{tab.label}
</button>
))}
</div>
<div className="space-y-4">
{tabArticles.map((item, idx) => (
<div key={idx} className="flex space-x-3">
<Image
src={item.thumbnailUrl || "/default-thumb.png"}
alt={item.title}
width={70}
height={70}
className="rounded w-[70px] h-[70px] object-cover"
/>
<div>
<p className="text-sm font-semibold leading-snug">
{item.title}
</p>
<p className="text-xs text-gray-500 mt-1">
{new Date(item.createdAt).toLocaleDateString("id-ID", {
day: "2-digit",
month: "long",
year: "numeric",
})}
</p>
</div>
</div>
))}
</div>
</div>
<div className="mt-6">
<h3 className="text-base font-semibold mb-2 text-gray-800 border-b pb-1 border-green-600 inline-block">
Recommended
</h3>
<div className="space-y-4">
<div className="relative">
<Image
src="/gaza.png"
alt="Recommended Article"
width={400}
height={200}
className="rounded-lg w-full h-auto object-cover"
/>
<div className="absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 text-white p-3 rounded-b-lg">
<p className="text-sm font-semibold leading-tight">
Bom Bunuh Diri Guncang Gereja di Damaskus, 20 Orang Tewas
dan Puluhan Terluka
</p>
<p className="text-xs text-gray-300 mt-1">
📅 23 JUNI 2025
</p>
</div>
</div>
<div className="space-y-3">
<div className="flex space-x-3">
<Image
src="/perang.png"
alt="OPM Serang Gereja"
width={80}
height={60}
className="rounded object-cover w-[80px] h-[60px]"
/>
<div>
<p className="text-sm font-semibold leading-snug">
OPM Mulai Kehilangan Simpati dari Masyarakat Papua Usai
Serang Gereja
</p>
<p className="text-xs text-gray-500 mt-1">
📅 15 JUNI 2025
</p>
</div>
</div>
<div className="flex space-x-3">
<Image
src="/jateng.png"
alt="Denda Merokok"
width={80}
height={60}
className="rounded object-cover w-[80px] h-[60px]"
/>
<div>
<p className="text-sm font-semibold leading-snug">
Jakarta Terapkan Denda Rp 250.000 bagi Warga yang
Merokok Sembarangan
</p>
<p className="text-xs text-gray-500 mt-1">
📅 13 JUNI 2025
</p>
</div>
</div>
<div className="flex space-x-3">
<Image
src="/investasi.jpg"
alt="Pengguna Internet"
width={80}
height={60}
className="rounded object-cover w-[80px] h-[60px]"
/>
<div>
<p className="text-sm font-semibold leading-snug">
Warga Indonesia Jadi Pengguna Internet via Ponsel
Terbanyak di Dunia
</p>
<p className="text-xs text-gray-500 mt-1">
📅 26 MEI 2025
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
}

View File

@ -1,8 +1,9 @@
"use client";
import { close, loading } from "@/config/swal";
import { getListArticle } from "@/service/article";
import { useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
type Article = {
id: number;
@ -53,7 +54,7 @@ export default function HeroNewsSection() {
setArticles(res?.data?.data || []);
setTotalPage(res?.data?.meta?.totalPage || 1);
} finally {
close();
// close();
}
}
@ -65,75 +66,79 @@ export default function HeroNewsSection() {
alt="Background"
width={272}
height={90}
className="w-[272px] h-[90px] object-cover border"
className="w-full md:w-[272px] h-[90px] object-cover border"
priority
/>
</div>
<div className="pb-5">
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-0.5 m-8 ">
{/* Artikel Utama */}
{articles.length > 0 && (
<div className="md:col-span-2 lg:col-span-3 relative">
<Image
src={
articles[0].thumbnailUrl ||
articles[0]?.files?.[0]?.file_url ||
"/default-image.jpg"
}
alt={articles[0].title}
width={800}
height={500}
className="w-full h-full max-h-[460px] object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/50 to-transparent p-6 flex flex-col justify-end">
<span className="text-xs bg-yellow-400 text-black px-2 py-0.5 inline-block mb-2 uppercase w-[130px]">
{articles[0].categories?.[0]?.title || "TANPA KATEGORI"}
</span>
<h2 className="text-sm md:text-xl lg:text-2xl font-bold text-white leading-snug mb-2 w-full md:w-9/12">
{articles[0].title}
</h2>
<p className="text-white text-xs">
{articles[0].createdByName} -{" "}
{new Date(articles[0].createdAt).toLocaleDateString("id-ID", {
day: "numeric",
month: "long",
year: "numeric",
})}
</p>
</div>
<Link href={`/detail/${articles[0]?.id}`}>
<Image
src={
articles[0].thumbnailUrl ||
articles[0]?.files?.[0]?.file_url ||
"/default-image.jpg"
}
alt={articles[0].title}
width={800}
height={500}
className="w-full h-full max-h-[460px] object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/50 to-transparent p-6 flex flex-col justify-end">
<span className="text-xs bg-yellow-400 text-black px-2 py-0.5 inline-block mb-2 uppercase w-[130px]">
{articles[0].categories?.[0]?.title || "TANPA KATEGORI"}
</span>
<h2 className="text-sm md:text-xl lg:text-2xl font-bold text-white leading-snug mb-2 w-full md:w-9/12">
{articles[0].title}
</h2>
<p className="text-white text-xs">
{articles[0].createdByName} -{" "}
{new Date(articles[0].createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</Link>
</div>
)}
{/* Artikel Tambahan */}
<div className="md:col-span-1 lg:col-span-2 grid grid-cols-1 sm:grid-cols-2 gap-2">
{articles.slice(1, 5).map((article, index) => (
<div key={index} className="relative">
<Image
src={
article.thumbnailUrl ||
article?.files?.[0]?.file_url ||
"/default-image.jpg"
}
alt={article.title}
width={400}
height={240}
className="w-full h-56 object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/40 to-transparent p-4 flex flex-col justify-end">
<span className="text-xs bg-yellow-400 text-black px-2 py-0.5 inline-block uppercase w-[130px]">
{article.categoryName || "TANPA KATEGORI"}
</span>
<h3 className="text-sm font-semibold text-white leading-snug mb-1">
{article.title}
</h3>
</div>
<Link href={`/detail/${articles[0]?.id}`}>
<Image
src={
article.thumbnailUrl ||
article?.files?.[0]?.file_url ||
"/default-image.jpg"
}
alt={article.title}
width={400}
height={240}
className="w-full h-56 object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/40 to-transparent p-4 flex flex-col justify-end">
<span className="text-xs bg-yellow-400 text-black px-2 py-0.5 inline-block uppercase w-[130px]">
{article.categoryName || "TANPA KATEGORI"}
</span>
<h3 className="text-sm font-semibold text-white leading-snug mb-1">
{article.title}
</h3>
</div>
</Link>
</div>
))}
</div>
</div>
{/* Iklan / Gambar Bawah */}
<div className="relative mt-10 mb-2 h-[188px] overflow-hidden flex items-center mx-8 border my-8">
<Image
src="/image-kolom.png"

View File

@ -1,4 +1,7 @@
"use client";
import { getListArticle } from "@/service/article";
import Image from "next/image";
import { useEffect, useState } from "react";
const data1 = {
main: {
@ -152,7 +155,6 @@ const data1 = {
],
};
// Disusun ulang agar cocok dengan struktur komponen
const data = {
leftMain: data1.main,
leftList: data1.left,
@ -163,44 +165,119 @@ const data = {
rightList: data1.bottomRight.slice(0, 3),
};
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 ITEMS_PER_PAGE = 2;
export default function LatestandPopular() {
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,
});
const [currentPage, setCurrentPage] = useState(1);
// useEffect(() => {
// const fetchData = async () => {
// const res = await getListArticle(); // ganti dengan fungsi fetch-mu
// setArticles(res.data || []);
// };
// fetchData();
// }, []);
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();
}
}
const totalPages = Math.ceil(articles.length / ITEMS_PER_PAGE);
const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
const currentArticles = articles.slice(
startIndex,
startIndex + ITEMS_PER_PAGE
);
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">
{/* Left: News Section */}
<div className="w-full lg:w-[750px]">
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
Latest Post
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 ">
{/* === LEFT COLUMN === */}
<div className=" w-full">
{data.leftList.map((item, i) => (
<div key={i}>
<div className="relative w-full aspect-video mb-5">
<Image
src={item.image}
alt={item.title}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover"
/>
<div className="absolute inset-0 bg-black/20" />
<span className="absolute bottom-1 left-1 bg-[#FFC600] text-black text-[11px] px-2 py-1 uppercase">
{item.category}
</span>
</div>
<div className=" text-black">
<h3 className=" font-semibold text-base mb-1">
{item.title}
</h3>
<p className="text-[#999999] text-sm font-serif">
{item.excerpt}
</p>
<p className="text-xs text-[#999999] mb-2 flex items-center gap-2">
by <span className="text-[#31942E]">{item?.author}</span>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
{currentArticles.map((article, index) => (
<div key={index}>
<div className="relative w-full aspect-video mb-3">
<Image
src={article.thumbnailUrl}
alt={"article.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover rounded"
/>
<div className="absolute inset-0 bg-black/20" />
<span className="absolute bottom-1 left-1 bg-[#FFC600] text-black text-[11px] px-2 py-1 uppercase">
{article?.categories?.map((cat) => cat.title).join(", ")}
</span>
</div>
<div className="text-black">
<h3 className="font-semibold text-base mb-1">
{article.title}
</h3>
<p className="text-[#999999] text-sm font-serif">
{article.description.length > 100
? `${article.description.slice(0, 100)}...`
: article.description}
</p>
<div className="text-xs text-[#999999] mb-2 flex items-center gap-2">
by{" "}
<span className="text-[#31942E]">
{article.createdByName}
</span>{" "}
|{" "}
<div className="text-xs mt-1.5 text-[#A0A0A0] space-x-2 flex items-center">
{/* Clock Icon + Date */}
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -215,7 +292,14 @@ export default function LatestandPopular() {
/>
</g>
</svg>{" "}
{item.date}{" "}
{new Date(article?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4"
@ -230,99 +314,12 @@ export default function LatestandPopular() {
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{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 32 32"
>
<path
fill="currentColor"
d="M16 8C7.664 8 1.25 15.344 1.25 15.344L.656 16l.594.656s5.848 6.668 13.625 7.282c.371.046.742.062 1.125.062s.754-.016 1.125-.063c7.777-.613 13.625-7.28 13.625-7.28l.594-.657l-.594-.656S24.336 8 16 8m0 2c2.203 0 4.234.602 6 1.406A6.9 6.9 0 0 1 23 15a6.995 6.995 0 0 1-6.219 6.969c-.02.004-.043-.004-.062 0c-.239.011-.477.031-.719.031c-.266 0-.523-.016-.781-.031A6.995 6.995 0 0 1 9 15c0-1.305.352-2.52.969-3.563h-.031C11.717 10.617 13.773 10 16 10m0 2a3 3 0 1 0 .002 6.002A3 3 0 0 0 16 12m-8.75.938A9 9 0 0 0 7 15c0 1.754.5 3.395 1.375 4.781A23.2 23.2 0 0 1 3.531 16a24 24 0 0 1 3.719-3.063zm17.5 0A24 24 0 0 1 28.469 16a23.2 23.2 0 0 1-4.844 3.781A8.93 8.93 0 0 0 25 15c0-.715-.094-1.398-.25-2.063z"
/>
</svg>{" "}
19
</p>
0
</div>
</div>
</div>
))}
</div>
{/* === RIGHT COLUMN === */}
<div className=" w-full">
{data.rightList.map((item, i) => (
<div key={i}>
<div className="relative w-full aspect-video mb-5">
<Image
src={item.image}
alt={item.title}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover"
/>
<div className="absolute inset-0 bg-black/20" />
<span className="absolute bottom-1 left-1 bg-[#FFC600] text-black text-[11px] px-2 py-1 uppercase">
{item.category}
</span>
</div>
<div className=" text-black">
<h3 className=" font-semibold text-base mb-1">
{item.title}
</h3>
<p className="text-[#999999] text-sm font-serif">
{item.excerpt}
</p>
<p className="text-xs text-[#999999] mb-2 flex items-center gap-2">
by <span className="text-[#31942E]">{item?.author}</span>
<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>{" "}
{item.date}{" "}
<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{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 32 32"
>
<path
fill="currentColor"
d="M16 8C7.664 8 1.25 15.344 1.25 15.344L.656 16l.594.656s5.848 6.668 13.625 7.282c.371.046.742.062 1.125.062s.754-.016 1.125-.063c7.777-.613 13.625-7.28 13.625-7.28l.594-.657l-.594-.656S24.336 8 16 8m0 2c2.203 0 4.234.602 6 1.406A6.9 6.9 0 0 1 23 15a6.995 6.995 0 0 1-6.219 6.969c-.02.004-.043-.004-.062 0c-.239.011-.477.031-.719.031c-.266 0-.523-.016-.781-.031A6.995 6.995 0 0 1 9 15c0-1.305.352-2.52.969-3.563h-.031C11.717 10.617 13.773 10 16 10m0 2a3 3 0 1 0 .002 6.002A3 3 0 0 0 16 12m-8.75.938A9 9 0 0 0 7 15c0 1.754.5 3.395 1.375 4.781A23.2 23.2 0 0 1 3.531 16a24 24 0 0 1 3.719-3.063zm17.5 0A24 24 0 0 1 28.469 16a23.2 23.2 0 0 1-4.844 3.781A8.93 8.93 0 0 0 25 15c0-.715-.094-1.398-.25-2.063z"
/>
</svg>{" "}
19
</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
@ -332,22 +329,25 @@ export default function LatestandPopular() {
className="object-cover"
/>
</div>
<div className="flex justify-center items-center space-x-2 pt-6">
<button className="px-3 py-1 border text-white rounded bg-[#31942E]">
1
<div className="flex justify-center gap-2">
<button
onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
disabled={currentPage === 1}
className="px-3 py-1 bg-gray-200 rounded disabled:opacity-50"
>
Previous
</button>
<button className="px-3 py-1 border border-gray-300 text-black rounded hover:bg-gray-100">
2
</button>
<button className="px-3 py-1 border border-gray-300 text-black rounded hover:bg-gray-100">
3
</button>
<span className="text-gray-400"></span>
<button className="px-3 py-1 border border-gray-300 text-black rounded hover:bg-gray-100">
19
</button>
<button className="px-3 py-1 border border-gray-300 text-black rounded hover:bg-gray-100">
&gt;
<span className="px-2 py-1">
{currentPage} / {totalPages}
</span>
<button
onClick={() =>
setCurrentPage((prev) => Math.min(prev + 1, totalPages))
}
disabled={currentPage === totalPages}
className="px-3 py-1 bg-gray-200 rounded disabled:opacity-50"
>
Next
</button>
</div>
</div>
@ -355,13 +355,17 @@ export default function LatestandPopular() {
<aside className="w-full lg:w-[345px]">
<div className="">
<h2 className="text-sm border-b-2 border-gray-300 font-bold mb-4">
Most Popular
Most Popularaa
</h2>
<div className=" w-full">
<div className="relative w-full aspect-video mb-5">
<Image
src={data1.main.image}
alt={data1.main.title}
src={
articles[0]?.thumbnailUrl ||
articles[0]?.files?.[0]?.file_url ||
"/default-image.jpg"
}
alt={"articles[0]?.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover"
@ -369,7 +373,7 @@ export default function LatestandPopular() {
<div className="absolute inset-0 bg-black/30" />
<div className="absolute bottom-0.5 left-2 text-white">
<h3 className=" font-semibold text-base mb-1">
{data1.main.title}
{articles[0]?.title}
</h3>
<p className=" text-xs mb-2 flex items-center gap-2">
<svg
@ -386,25 +390,32 @@ export default function LatestandPopular() {
/>
</g>
</svg>{" "}
{data1.main.date}{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
<div className="space-y-5">
{data.bottomRightList.map((item, i) => (
<div key={i} className="flex gap-3">
{articles?.slice(1, 4).map((article, index) => (
<div key={index} className="flex gap-3">
<div className="relative w-[120px] h-[86px] shrink-0">
<Image
src={item.image}
alt={item.title}
src={article?.thumbnailUrl}
alt={"article?.title"}
fill
className="object-cover"
/>
</div>
<div>
<h4 className="text-sm font-semibold mb-3">
{item.title}
{article?.title}
</h4>
<p className="text-xs text-gray-500 flex gap-2 items-center">
<svg
@ -421,7 +432,14 @@ export default function LatestandPopular() {
/>
</g>
</svg>{" "}
{item.date}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>

View File

@ -1,14 +1,8 @@
import {
Clock,
Facebook,
Instagram,
RefreshCcwIcon,
ThumbsUpIcon,
Twitter,
UserRoundPlus,
Youtube,
} from "lucide-react";
"use client";
import { getListArticle } from "@/service/article";
import Image from "next/image";
import { useEffect, useState } from "react";
const data1 = {
main: {
@ -175,23 +169,76 @@ const popularPosts = [
},
];
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">
{/* Left: News Section */}
<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 ">
{/* === LEFT COLUMN === */}
<div className=" w-full">
<div className="relative w-full aspect-video mb-5">
<Image
src={data.leftMain.image}
alt={data.leftMain.title}
src={
articles[0]?.files?.[0]?.file_url || "/default-image.jpg"
}
alt={"articles[0]?.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover"
@ -199,7 +246,7 @@ export default function Latest() {
<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">
{data.leftMain.title}
{articles[0]?.title}
</h3>
<p className=" text-xs mb-2 flex items-center gap-2">
<svg
@ -216,27 +263,34 @@ export default function Latest() {
/>
</g>
</svg>{" "}
{data.rightMain.date}{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
<div className="space-y-5">
{data.leftList.map((item, i) => (
<div key={i} className="flex gap-3">
{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={item.image}
alt={item.title}
src={article?.thumbnailUrl}
alt={"article?.title"}
fill
className="object-cover"
/>
</div>
<div>
<h4 className="text-sm font-semibold mb-3">
{item.title}
{article.title}
</h4>
<p className="text-xs text-gray-500 flex gap-2 items-center">
<p className="text-xs text-gray-500 flex gap-2 articles-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -251,7 +305,14 @@ export default function Latest() {
/>
</g>
</svg>{" "}
{item.date}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
@ -259,12 +320,13 @@ export default function Latest() {
</div>
</div>
{/* === RIGHT COLUMN === */}
<div className="w-full">
<div className="relative w-full aspect-video mb-5">
<Image
src={data.rightMain.image}
alt={data.rightMain.title}
src={
articles[0]?.files?.[0]?.file_url || "/default-image.jpg"
}
alt={"articles[0]?.title"}
fill
sizes="(max-width: 1024px) 100vw, 33vw"
className="object-cover "
@ -272,7 +334,7 @@ export default function Latest() {
<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">
{data.leftMain.title}
{articles[0]?.title}
</h3>
<p className=" text-xs mb-2 flex items-center gap-2">
<svg
@ -289,27 +351,34 @@ export default function Latest() {
/>
</g>
</svg>{" "}
{data.rightMain.date}{" "}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
<div className="space-y-5">
{data.rightList.map((item, i) => (
<div key={i} className="flex gap-3">
{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={item.image}
alt={item.title}
src={article?.thumbnailUrl}
alt={"article?.title"}
fill
className="object-cover "
/>
</div>
<div>
<h4 className="text-sm font-semibold mb-3">
{item.title}
{article?.title}
</h4>
<p className="text-xs text-gray-500 flex gap-2 items-center">
<p className="text-xs text-gray-500 flex gap-2 articles-center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -324,7 +393,14 @@ export default function Latest() {
/>
</g>
</svg>{" "}
{item.date}
{new Date(articles[0]?.createdAt).toLocaleDateString(
"id-ID",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</p>
</div>
</div>
@ -369,21 +445,20 @@ export default function Latest() {
</h2>
<div className="space-y-8">
{popularPosts.map((post) => (
<div key={post.id} className="space-y-3">
{/* Title, Meta, Image in Flex */}
{popularPosts.slice(1, 5).map((post, index) => (
<div key={index} className="space-y-3">
<div
className={`flex gap-4 ${
post.image ? "flex-col md:flex-row" : "flex-col"
post.files?.[0]?.file_url
? "flex-col md:flex-row"
: "flex-col"
}`}
>
{/* Text Content (Title + Meta) */}
<div className="flex-1">
<h3 className="text-base sm:text-lg md:text-sm font-bold leading-tight">
{post.title}
{post?.title}
</h3>
<div className="text-xs mt-1.5 text-[#A0A0A0] space-x-2 flex items-center">
{/* Clock Icon + Date */}
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -398,7 +473,14 @@ export default function Latest() {
/>
</g>
</svg>{" "}
{post.date}{" "}
{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"
@ -417,13 +499,12 @@ export default function Latest() {
</div>
</div>
{/* Image on the right (md+) or bottom (sm) */}
{post.image && (
{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.image}
alt={post.title}
src={post?.thumbnailUrl}
alt={"post?.title"}
fill
className="object-cover rounded"
/>
@ -432,9 +513,8 @@ export default function Latest() {
)}
</div>
{/* Excerpt - always below */}
<p className="text-[13px] text-[#3D4248] line-clamp-2 mb-3">
{post.excerpt}
{post.description}
</p>
</div>
))}

View File

@ -1,8 +1,6 @@
"use client";
import { close } from "@/config/swal";
import { getListArticle } from "@/service/article";
import { Clock } from "lucide-react";
import { getPossibleInstrumentationHookFilenames } from "next/dist/build/utils";
import Image from "next/image";
import { useEffect, useState } from "react";
@ -55,7 +53,7 @@ export default function Beranda() {
setPosts(res?.data?.data || []);
setTotalPage(res?.data?.meta?.totalPage || 1);
} finally {
close();
// close();
}
}
return (

3
package-lock.json generated
View File

@ -2798,6 +2798,7 @@
"version": "19.1.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
"dev": true,
"dependencies": {
"csstype": "^3.0.2"
}
@ -2806,7 +2807,7 @@
"version": "19.1.6",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
"integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
"devOptional": true,
"dev": true,
"peerDependencies": {
"@types/react": "^19.0.0"
}

BIN
public/bom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 KiB