114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import {
|
|
getArticleCategories,
|
|
ArticleCategory,
|
|
} from "@/service/categories/article-categories";
|
|
import { useTranslations } from "next-intl";
|
|
import { RevealR } from "../ui/RevealR";
|
|
|
|
export default function Category() {
|
|
const t = useTranslations("MediaUpdate");
|
|
const [categories, setCategories] = useState<ArticleCategory[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
// Fetch article categories
|
|
useEffect(() => {
|
|
async function fetchCategories() {
|
|
try {
|
|
const response = await getArticleCategories();
|
|
if (response?.data?.success && response.data.data) {
|
|
// Filter hanya kategori yang aktif dan published
|
|
const activeCategories = response.data.data.filter(
|
|
(category: ArticleCategory) =>
|
|
category.isActive && category.isPublish,
|
|
);
|
|
setCategories(activeCategories);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching article categories:", error);
|
|
// Fallback to static categories if API fails
|
|
setCategories([]);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
fetchCategories();
|
|
}, []);
|
|
|
|
// Fallback categories jika API gagal atau tidak ada data
|
|
const fallbackCategories = [
|
|
"PON XXI",
|
|
"OPERASI KETUPAT 2025",
|
|
"HUT HUMAS KE-74",
|
|
"OPERASI ZEBRA 2025",
|
|
"OPERASI MANTAP PRAJA & PILKADA 2024",
|
|
"PERS RILIS",
|
|
"LIPUTAN KEGIATAN",
|
|
"UNGKAP KASUS",
|
|
"INFOGRAFIS",
|
|
"SEPUTAR PRESTASI",
|
|
];
|
|
|
|
const displayCategories =
|
|
categories.length > 0 ? categories : fallbackCategories;
|
|
|
|
return (
|
|
<RevealR>
|
|
<section className="px-4 py-10">
|
|
<div className="max-w-[1350px] mx-auto bg-white dark:bg-default-50 dark:border dark:border-slate-50 rounded-xl shadow-md p-6">
|
|
<h2 className="text-xl font-semibold mb-5">
|
|
{loading
|
|
? t("loadCategory")
|
|
: `${displayCategories.length} ${t("category")}`}
|
|
</h2>
|
|
|
|
{loading ? (
|
|
// Loading skeleton
|
|
<div className="flex flex-wrap gap-3">
|
|
{Array.from({ length: 10 }).map((_, index) => (
|
|
<div
|
|
key={index}
|
|
className="px-4 py-2 rounded border border-gray-200 bg-gray-100 animate-pulse"
|
|
>
|
|
<div className="h-4 w-20 bg-gray-300 rounded"></div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="flex flex-wrap gap-3">
|
|
{displayCategories.map((category, index) => {
|
|
// Handle both API data and fallback data
|
|
const categoryTitle =
|
|
typeof category === "string" ? category : category.title;
|
|
const categorySlug =
|
|
typeof category === "string"
|
|
? category.toLowerCase().replace(/\s+/g, "-")
|
|
: category.slug;
|
|
|
|
return (
|
|
<button
|
|
key={index}
|
|
className="px-4 py-2 rounded border border-gray-300 text-gray-700 dark:text-white text-sm font-medium hover:bg-gray-100 hover:border-gray-400 transition-all duration-200"
|
|
onClick={() => {
|
|
// Navigate to category page or search by category
|
|
console.log(
|
|
`Category clicked: ${categoryTitle} (${categorySlug})`,
|
|
);
|
|
// TODO: Implement navigation to category page
|
|
}}
|
|
>
|
|
{categoryTitle}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
</RevealR>
|
|
);
|
|
}
|