-
+
-
+
{articleDetail?.customCreatorName ||
articleDetail?.createdByName}
-
-
- {new Date(
- articleDetail?.publishedAt ?? articleDetail?.createdAt
- ).toLocaleDateString("id-ID", {
+ {new Date(
+ articleDetail?.publishedAt ?? articleDetail?.createdAt,
+ )
+ .toLocaleString("id-ID", {
day: "numeric",
month: "long",
year: "numeric",
- })}
-
+ hour: "2-digit",
+ minute: "2-digit",
+ hour12: false,
+ timeZone: "Asia/Jakarta",
+ })
+ .replace("pukul ", "")}{" "}
+ WIB
in
{articleDetail?.categories?.[0]?.title}
@@ -446,7 +451,7 @@ export default function DetailContent() {
- Komentar *
+ Komentar *
@@ -676,7 +681,7 @@ export default function DetailContent() {
htmlFor="nama"
className="block text-sm font-medium mb-1"
>
- Nama
*
+ Nama
*
- Email
*
+ Email
*
KIRIM KOMENTAR
@@ -737,7 +742,7 @@ export default function DetailContent() {
Kirim
@@ -778,7 +783,7 @@ export default function DetailContent() {
day: "2-digit",
month: "long",
year: "numeric",
- }
+ },
)}
💬 0
diff --git a/components/landing-page/development.tsx b/components/landing-page/development.tsx
new file mode 100644
index 0000000..5f8c521
--- /dev/null
+++ b/components/landing-page/development.tsx
@@ -0,0 +1,136 @@
+"use client";
+import { useEffect, useState } from "react";
+import Image from "next/image";
+import { getListArticle } from "@/service/article";
+import Link from "next/link";
+
+type Article = {
+ id: number;
+ title: string;
+ description: string;
+ categoryName: string;
+ slug: string;
+ createdAt: string;
+ publishedAt: string;
+ createdByName: string;
+ customCreatorName: string;
+ thumbnailUrl: string;
+ categories: { title: string }[];
+ files: { fileUrl: string; file_alt: string }[];
+};
+
+export default function Development() {
+ const [articles, setArticles] = useState
([]);
+ const [page, setPage] = useState(1);
+ const [totalPage, setTotalPage] = useState(1);
+
+ useEffect(() => {
+ initState();
+ }, [page]);
+
+ async function initState() {
+ const req = {
+ limit: "10",
+ page,
+ search: "",
+ categorySlug: "",
+ 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);
+ }
+ }
+
+ // Format tanggal ke gaya lokal
+ const formatDate = (dateString: string) => {
+ const date = new Date(dateString);
+ return date.toLocaleDateString("id-ID", {
+ day: "2-digit",
+ month: "long",
+ year: "numeric",
+ });
+ };
+
+ // Mapping struktur seperti dummy sebelumnya
+ const leftMain = articles[0];
+ const leftList = articles.slice(1, 4);
+ const centerMain = articles[4];
+ const centerList = articles.slice(5, 8);
+ const rightMain = articles[8];
+ const rightList = articles.slice(9, 12);
+
+ return (
+
+
+
+
+
+
+
+ {articles.slice(0, 6).map((item) => (
+
+
+
+
+
+
+
+
+ BERITA OPINI
+
+
+
+
+ {item.title}
+
+
+
+ By{" "}
+
+ {item.customCreatorName}
+
+
+
+
+ {new Date(item.publishedAt).toLocaleDateString("id-ID", {
+ day: "numeric",
+ month: "long",
+ year: "numeric",
+ })}
+
+
+
+ ))}
+
+
+
+
+
+
+ );
+}
diff --git a/components/landing-page/header.tsx b/components/landing-page/header.tsx
new file mode 100644
index 0000000..fca78d1
--- /dev/null
+++ b/components/landing-page/header.tsx
@@ -0,0 +1,232 @@
+"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;
+ slug: string;
+ createdByName: string;
+ publishedAt: string;
+ customCreatorName: string;
+ thumbnailUrl: string;
+ categories: { title: string }[];
+ files: { fileUrl: string; file_alt: string }[];
+};
+
+export default function Header() {
+ const [articles, setArticles] = useState([]);
+
+ useEffect(() => {
+ const fetchArticles = async () => {
+ const req = {
+ limit: "10",
+ page: 1,
+ search: "",
+ categorySlug: "",
+ sort: "desc",
+ isPublish: true,
+ sortBy: "created_at",
+ };
+
+ const res = await getListArticle(req);
+ setArticles(res?.data?.data || []);
+ };
+
+ fetchArticles();
+ }, []);
+
+ const flashArticles = articles.slice(0, 8);
+ const mainArticle = articles[8] || articles[0];
+ const recentPosts = articles.slice(1, 5);
+
+ return (
+
+ {/* FLASH STRIP */}
+
+
+
Flash
+ ⚡
+
+
LOAD MORE ➜
+
+
+
+
+ {flashArticles.map((item) => (
+
+
+
+
+
+ {/* dark overlay with text */}
+
+
{item.title}
+
+
+ {item.categoryName ||
+ item.categories?.[0]?.title ||
+ "Berita"}
+
+ ●
+
+
+
+ {/* play icon */}
+
+
+ ))}
+
+
+
+ {/* Main Layout */}
+
+ {/* LEFT SIDE – MAIN ARTICLE */}
+ {mainArticle ? (
+
+
+
+
+ {/* White Card Overlay */}
+
+
+ {mainArticle.categoryName ||
+ mainArticle.categories?.[0]?.title ||
+ "Berita"}
+
+
+
+ {mainArticle.title}
+
+
+
+
+ By{" "}
+ {mainArticle.customCreatorName ||
+ mainArticle.createdByName ||
+ "Admin"}
+
+ •
+
+ {new Date(mainArticle.publishedAt).toLocaleDateString(
+ "id-ID",
+ {
+ day: "2-digit",
+ month: "long",
+ year: "numeric",
+ },
+ )}
+
+
+
+
+
+ ) : (
+
Loading...
+ )}
+
+ {/* RIGHT SIDE – RECENT POSTS */}
+
+
Recent Posts
+
+
+ {recentPosts.map((item) => (
+
+
+
+
+
+
+
+ {item.title}
+
+
+ {new Date(item.publishedAt).toLocaleDateString("id-ID", {
+ day: "2-digit",
+ month: "long",
+ year: "numeric",
+ })}
+
+
+
+ ))}
+
+
+
+
+ {/* LOAD MORE */}
+
+
+ {/* KOLOM PPS BOTTOM BANNER */}
+
+
+
+
+ );
+}
diff --git a/components/landing-page/health.tsx b/components/landing-page/health.tsx
new file mode 100644
index 0000000..8091d47
--- /dev/null
+++ b/components/landing-page/health.tsx
@@ -0,0 +1,186 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import Image from "next/image";
+import Link from "next/link";
+import { getListArticle } from "@/service/article";
+
+type Article = {
+ id: number;
+ title: string;
+ description: string;
+ categoryName: string;
+ createdAt: string;
+ publishedAt: string;
+ slug: string;
+ createdByName: string;
+ customCreatorName?: string;
+ thumbnailUrl?: string;
+ categories?: { title: string }[];
+};
+
+export default function NewsTerkini() {
+ const [articles, setArticles] = useState([]);
+ const [popular, setPopular] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ loadData();
+ }, []);
+
+ async function loadData() {
+ setLoading(true);
+
+ try {
+ const res = await getListArticle({
+ limit: "20",
+ page: 1,
+ search: "",
+ isPublish: true,
+ sort: "desc",
+ sortBy: "created_at",
+ });
+
+ const data = res?.data?.data || [];
+ setArticles(data.slice(0, 5));
+ setPopular(data.slice(0, 5));
+ } catch (err) {
+ console.log(err);
+ }
+
+ setLoading(false);
+ }
+
+ const formatDate = (d: string) =>
+ new Date(d).toLocaleDateString("id-ID", {
+ day: "numeric",
+ month: "long",
+ year: "numeric",
+ });
+
+ if (loading)
+ return (
+
+ Memuat berita terbaru...
+
+ );
+
+ return (
+
+
+
BERITA TERKINI
+
+
+
+ {articles.map((item) => (
+
+
+
+ {/* CATEGORY */}
+
+ {item.categoryName || "Kategori"}
+
+
+ {/* JUDUL */}
+
+ {item.title}
+
+
+ {/* DESKRIPSI */}
+
+ {item.description}
+
+
+ {/* AUTHOR + DATE */}
+
+ By {item.customCreatorName || item.createdByName} —{" "}
+ {formatDate(item.publishedAt)}
+
+
+
+
+
+
+
+ ))}
+
+
+ {/* LOAD MORE */}
+
+ LOAD MORE ↓
+
+
+
+
+
TERBANYAK DIBAGIKAN
+
+
+
+ {popular.map((item, index) => (
+
+ {/* NOMOR */}
+
+ {(index + 1).toString().padStart(2, "0")}
+
+
+
+
+ {item.categories?.[0]?.title || "Kategori"}
+
+
+ {item.title}
+
+
+ {formatDate(item.createdAt)}
+
+
+
+ {/* THUMBNAIL KECIL */}
+
+
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/components/landing-page/latest-news.tsx b/components/landing-page/latest-news.tsx
new file mode 100644
index 0000000..59864ea
--- /dev/null
+++ b/components/landing-page/latest-news.tsx
@@ -0,0 +1,126 @@
+"use client";
+
+import { getListArticle } from "@/service/article";
+import { ChevronDown } from "lucide-react";
+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;
+ slug: string;
+ createdAt: string;
+ publishedAt: string;
+ createdByName: string;
+ customCreatorName: string;
+ thumbnailUrl: string;
+ categories: { title: string }[];
+ files: { fileUrl: string; file_alt: string }[];
+};
+
+export default function News() {
+ const [page, setPage] = useState(1);
+ const [totalPage, setTotalPage] = useState(1);
+ const [articles, setArticles] = useState([]);
+ const [showData, setShowData] = useState("6");
+ const [search] = useState("");
+ const [selectedCategories] = useState("");
+ const [startDateValue] = 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 (
+
+
+ {/* TITLE */}
+
+
+ {/* GRID 4 KOLOM */}
+
+ {articles.slice(0, 4).map((item) => (
+
+
+ {/* GAMBAR */}
+
+
+
+ {/* BADGE CATEGORY DI DALAM GAMBAR */}
+
+
+ {item.categoryName || "Kategori"}
+
+
+
+
+ {/* JUDUL */}
+
+ {item.title}
+
+
+ {/* AUTHOR + DATE */}
+
+
+ By {item.customCreatorName || item.createdByName || "Admin"}
+
+ -
+
+ {new Date(item.publishedAt).toLocaleDateString("id-ID", {
+ day: "numeric",
+ month: "long",
+ year: "numeric",
+ })}
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/landing-page/navbar.tsx b/components/landing-page/navbar.tsx
index 68b0bc5..25a0f81 100644
--- a/components/landing-page/navbar.tsx
+++ b/components/landing-page/navbar.tsx
@@ -1,133 +1,180 @@
"use client";
-import { Lock, Menu } from "lucide-react";
+
+import { Search } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
-import { Button } from "../ui/button";
import { usePathname } from "next/navigation";
export default function Navbar() {
const pathname = usePathname();
+ const isActive = (href: any) => {
+ return pathname === href || pathname.startsWith(href + "/");
+ };
+
return (
- <>
-
-
-
-
-
+
+
+ {/* Left: Logo */}
+
+
+
+
+
+ {/* Social Icons */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- {/* Kiri: Hamburger */}
-
-
-
+ {/* Middle Menu */}
+
+
+
+ Beranda
+
- {/* Tengah: Menu Utama */}
-
- {[
- { href: "/", label: "Beranda" },
- { href: "/category/main-activity", label: "Giat Utama" },
- { href: "/category/service", label: "Pelayanan" },
- { href: "/category/inspiration", label: "Inspirasi" },
- { href: "/category/opinion", label: "Opini" },
- {
- href: "/category/police-achievements",
- label: "Prestasi Polri",
- },
- ].map((item) => {
- const isActive = pathname === item.href;
+
+ Giat Utama
+
- return (
-
- {item.label}
-
- );
- })}
+
+ Pelayanan
+
+
+
+ Inspirasi
+
+
+ Opini
+
- {/* Kanan: Search Icon */}
-
-
-
-
- Login
-
-
-
+
+
document.documentElement.classList.toggle("dark")}
+ className="w-10 h-5 rounded-full bg-gray-300 dark:bg-gray-700 relative transition-all"
+ >
+
+
+
+ {/* BURGER BUTTON (mobile menu) */}
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ LOGIN
+
- >
+
);
}
diff --git a/components/landing-page/opinion-news.tsx b/components/landing-page/opinion-news.tsx
new file mode 100644
index 0000000..90621f1
--- /dev/null
+++ b/components/landing-page/opinion-news.tsx
@@ -0,0 +1,126 @@
+"use client";
+
+import { getListArticle } from "@/service/article";
+import { ChevronDown } from "lucide-react";
+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;
+ slug: string;
+ createdAt: string;
+ publishedAt: string;
+ createdByName: string;
+ customCreatorName: string;
+ thumbnailUrl: string;
+ categories: { title: string }[];
+ files: { fileUrl: string; file_alt: string }[];
+};
+
+export default function OpinionNews() {
+ const [page, setPage] = useState(1);
+ const [totalPage, setTotalPage] = useState(1);
+ const [articles, setArticles] = useState
([]);
+ const [showData, setShowData] = useState("6");
+ const [search] = useState("");
+ const [selectedCategories] = useState("");
+ const [startDateValue] = 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 (
+
+
+ {/* TITLE */}
+
+
+ {/* GRID 4 KOLOM */}
+
+ {articles.slice(0, 4).map((item) => (
+
+
+ {/* GAMBAR */}
+
+
+
+ {/* BADGE CATEGORY DI DALAM GAMBAR */}
+
+
+ {item.categoryName || "Kategori"}
+
+
+
+
+ {/* JUDUL */}
+
+ {item.title}
+
+
+ {/* AUTHOR + DATE */}
+
+
+ By {item.customCreatorName || item.createdByName || "Admin"}
+
+ -
+
+ {new Date(item.publishedAt).toLocaleDateString("id-ID", {
+ day: "numeric",
+ month: "long",
+ year: "numeric",
+ })}
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/landing-page/youtube-selection.tsx b/components/landing-page/youtube-selection.tsx
new file mode 100644
index 0000000..2243f66
--- /dev/null
+++ b/components/landing-page/youtube-selection.tsx
@@ -0,0 +1,151 @@
+import { Eye, Heart, MessageCircle } from "lucide-react";
+import Image from "next/image";
+
+interface VideoItem {
+ id: number;
+ title: string;
+ thumbnail: string;
+ duration: string;
+ publishedAt: string;
+ views: string;
+ likes: string;
+ comments: string;
+}
+
+const sampleVideos: VideoItem[] = [
+ {
+ id: 1,
+ title: "Cuplikan Kegiatan Presiden di IKN",
+ thumbnail: "/yt/thumb1.jpg",
+ duration: "12:30",
+ publishedAt: "2 jam yang lalu",
+ views: "12K",
+ likes: "230",
+ comments: "45",
+ },
+ {
+ id: 2,
+ title: "Pembangunan MRT Fase Berikutnya Resmi Dimulai",
+ thumbnail: "/yt/thumb2.jpg",
+ duration: "08:12",
+ publishedAt: "5 jam yang lalu",
+ views: "9.4K",
+ likes: "180",
+ comments: "30",
+ },
+ {
+ id: 3,
+ title: "Wilayah Indonesia Siap Hadapi Cuaca Ekstrem",
+ thumbnail: "/yt/thumb3.jpg",
+ duration: "05:50",
+ publishedAt: "1 hari lalu",
+ views: "21K",
+ likes: "540",
+ comments: "121",
+ },
+ {
+ id: 4,
+ title: "Peningkatan Ekonomi Regional Terus Dijaga",
+ thumbnail: "/yt/thumb4.jpg",
+ duration: "10:44",
+ publishedAt: "2 hari lalu",
+ views: "18K",
+ likes: "420",
+ comments: "88",
+ },
+ {
+ id: 5,
+ title: "Laporan Khusus Perkembangan Industri Kreatif",
+ thumbnail: "/yt/thumb5.jpg",
+ duration: "14:02",
+ publishedAt: "3 hari lalu",
+ views: "30K",
+ likes: "830",
+ comments: "200",
+ },
+ {
+ id: 6,
+ title: "Paparan Menteri Perhubungan Soal Transportasi",
+ thumbnail: "/yt/thumb6.jpg",
+ duration: "07:21",
+ publishedAt: "4 hari lalu",
+ views: "9K",
+ likes: "114",
+ comments: "26",
+ },
+];
+
+export default function YouTubeSection() {
+ return (
+
+ {/* Header Channel */}
+
+
+
+
YouTube • Channel Resmi
+
+ Lebih dari 3.5 juta pengikut • 12k video
+
+
+
+
+ Subscribe
+
+
+
+ {/* Grid Video */}
+
+ {sampleVideos.map((v) => (
+
+
+
+
+
+ {v.duration}
+
+
+
+
+ {v.title}
+
+
+
{v.publishedAt}
+
+
+
+ {v.views}
+
+
+ {v.likes}
+
+
+ {v.comments}
+
+
+
+ ))}
+
+
+ {/* Pagination */}
+
+
+ Lihat Selanjutnya →
+
+
+
+ );
+}
diff --git a/public/bhayangkara-logo.png b/public/bhayangkara-logo.png
new file mode 100644
index 0000000..4b400c7
Binary files /dev/null and b/public/bhayangkara-logo.png differ
diff --git a/public/yt-logo.png b/public/yt-logo.png
new file mode 100644
index 0000000..cbb41e7
Binary files /dev/null and b/public/yt-logo.png differ