qudoco-fe/components/landing-page/headers-news-services.tsx

271 lines
8.8 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 Image from "next/image";
import { motion, AnimatePresence } from "framer-motion";
import { X, ChevronLeft, ChevronRight } from "lucide-react";
import { useEffect, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
const data = [
{
id: 1,
title:
"Bharatu Mardi Hadji Gugur Saat Bertugas, Diganjar Kenaikan Pangkat Luar Biasa",
image: "/image/bharatu.jpg",
},
{
id: 2,
title: "Pelayanan Publik Terus Ditingkatkan Demi Kenyamanan Masyarakat",
image: "/dummy/news-2.jpg",
},
{
id: 3,
title: "Inovasi Teknologi Jadi Fokus Pengembangan Layanan",
image: "/dummy/news-3.jpg",
},
];
const data1 = [
{
id: 1,
title: "Novita Hardini: Jangan Sampai Pariwisata Meminggirkan Warga Lokal",
image: "/image/novita2.png",
excerpt:
"PARLEMENTARIA, Mandalika Anggota Komisi VII DPR RI, Novita Hardini, menyoroti dampak sosial ekonomi dari pembangunan kawasan pariwisata...",
date: "7 November 2024",
category: "BERITA KOMISI 7",
tag: "DPR",
},
{
id: 2,
title: "Pelayanan Publik Terus Ditingkatkan Demi Kenyamanan Masyarakat",
image: "/dummy/news-2.jpg",
excerpt:
"Pelayanan publik terus ditingkatkan untuk menjawab kebutuhan masyarakat...",
date: "6 November 2024",
category: "BERITA",
tag: "NASIONAL",
},
{
id: 3,
title: "Inovasi Teknologi Jadi Fokus Pengembangan Layanan",
image: "/dummy/news-3.jpg",
excerpt:
"Transformasi digital menjadi fokus utama pengembangan layanan publik...",
date: "5 November 2024",
category: "TEKNOLOGI",
tag: "INOVASI",
},
];
export default function NewsAndServicesHeader() {
// 🔹 STATE DIPISAH
const [activeHeader, setActiveHeader] = useState(0);
const [activeModal, setActiveModal] = useState(0);
const [open, setOpen] = useState(false);
const [mounted, setMounted] = useState(false);
const searchParams = useSearchParams();
const router = useRouter();
useEffect(() => {
setMounted(true);
}, []);
// 🔹 AUTO OPEN MODAL
useEffect(() => {
if (!mounted) return;
const highlight = searchParams.get("highlight");
if (highlight === "1") {
setActiveModal(activeHeader); // clone posisi header
setOpen(true);
}
}, [mounted, searchParams, activeHeader]);
const closeModal = () => {
setOpen(false);
router.replace("/news-services");
};
// ===== HEADER NAV =====
const headerPrev = () =>
setActiveHeader((p) => (p === 0 ? data.length - 1 : p - 1));
const headerNext = () =>
setActiveHeader((p) => (p === data.length - 1 ? 0 : p + 1));
// ===== MODAL NAV =====
const modalPrev = () =>
setActiveModal((p) => (p === 0 ? data.length - 1 : p - 1));
const modalNext = () =>
setActiveModal((p) => (p === data.length - 1 ? 0 : p + 1));
if (!mounted) return null;
return (
<>
{/* ================= HEADER ================= */}
{/* ================= HEADER ================= */}
<section className="relative w-full bg-[#f8f8f8] py-24">
<div className="container mx-auto px-6 relative">
{/* ===== OUTER NAVIGATION ===== */}
<button
onClick={headerPrev}
className="hidden lg:flex absolute -left-6 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white shadow-md items-center justify-center z-10"
>
<ChevronLeft />
</button>
<button
onClick={headerNext}
className="hidden lg:flex absolute -right-6 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white shadow-md items-center justify-center z-10"
>
<ChevronRight />
</button>
<div className="flex flex-col lg:flex-row items-center gap-14">
{/* IMAGE */}
<div className="relative w-full lg:w-1/2">
<div className="relative h-[420px] rounded-3xl overflow-hidden">
<Image
src={data1[activeHeader].image}
alt={data1[activeHeader].title}
fill
className="object-cover"
priority
/>
</div>
{/* DOTS */}
<div className="flex justify-center gap-2 mt-4">
{data1.map((_, i) => (
<span
key={i}
className={`h-2.5 rounded-full transition-all ${
activeHeader === i
? "w-8 bg-[#b07c18]"
: "w-2.5 bg-gray-300"
}`}
/>
))}
</div>
</div>
{/* CONTENT */}
<div className="w-full lg:w-1/2">
<h1 className="text-4xl lg:text-5xl font-bold leading-tight mb-6">
{data1[activeHeader].title}
</h1>
<div className="flex flex-wrap items-center gap-3 text-sm text-gray-500 mb-5">
<span>{data1[activeHeader].date}</span>
<span></span>
<span>{data1[activeHeader].category}</span>
<span></span>
<span className="px-2 py-0.5 rounded bg-[#f2c94c] text-black text-xs font-semibold">
{data1[activeHeader].tag}
</span>
</div>
<p className="text-gray-700 leading-relaxed mb-8">
{data1[activeHeader].excerpt}
</p>
<button
onClick={() => setOpen(true)}
className="inline-flex items-center justify-center rounded-xl bg-[#b07c18] px-7 py-3 text-white font-medium hover:opacity-90 transition"
>
Baca Selengkapnya
</button>
</div>
</div>
{/* ===== SEARCH SECTION ===== */}
<div className="mt-20">
<div className="max-w-3xl mx-auto flex items-center bg-white rounded-2xl shadow-md overflow-hidden border">
<div className="px-4 text-gray-400">🔍</div>
<input
type="text"
placeholder="Cari berita, artikel, atau topik..."
className="flex-1 px-4 py-4 outline-none"
/>
<button className="bg-[#b07c18] text-white px-8 py-4 font-medium">
Cari
</button>
</div>
</div>
</div>
</section>
{/* ================= MODAL ================= */}
<AnimatePresence>
{open && (
<motion.div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<motion.div
className="relative w-[90%] max-w-5xl rounded-3xl overflow-hidden bg-[#9c8414]"
initial={{ scale: 0.95, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.95, opacity: 0 }}
>
<button
onClick={closeModal}
className="absolute top-4 right-4 z-10 w-10 h-10 rounded-full bg-black/40 text-white flex items-center justify-center"
>
<X />
</button>
<div className="relative h-[520px]">
<Image
src={data[activeModal].image}
alt={data[activeModal].title}
fill
className="object-cover"
priority
/>
<div className="absolute bottom-6 left-6 right-6 text-white">
<h2 className="text-xl md:text-2xl font-semibold">
{data[activeModal].title}
</h2>
</div>
<button
onClick={modalPrev}
className="absolute left-4 top-1/2 -translate-y-1/2 w-10 h-10 rounded-full bg-black/40 text-white"
>
<ChevronLeft />
</button>
<button
onClick={modalNext}
className="absolute right-4 top-1/2 -translate-y-1/2 w-10 h-10 rounded-full bg-black/40 text-white"
>
<ChevronRight />
</button>
</div>
<div className="flex justify-center gap-2 py-4">
{data.map((_, i) => (
<button
key={i}
onClick={() => setActiveModal(i)}
className={`w-2.5 h-2.5 rounded-full ${
activeModal === i ? "bg-white" : "bg-white/40"
}`}
/>
))}
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</>
);
}