"use client"; import { useEffect, useState, useCallback } from "react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Search, Plus, Eye, Pencil, Trash2 } from "lucide-react"; import Link from "next/link"; import { getArticlePagination, deleteArticle } from "@/service/article"; import { formatDate } from "@/utils/global"; import { close, loading } from "@/config/swal"; import Cookies from "js-cookie"; import Swal from "sweetalert2"; import type { ArticleContentKind } from "@/constants/article-content-types"; import { ARTICLE_KIND_LABEL, articleListPath } from "@/constants/article-content-types"; type Props = { kind: ArticleContentKind; typeId: number; }; export default function NewsArticleList({ kind, typeId }: Props) { const [articles, setArticles] = useState([]); const [page, setPage] = useState(1); const [totalPage, setTotalPage] = useState(1); const [search, setSearch] = useState(""); const [debouncedSearch, setDebouncedSearch] = useState(""); const [levelId, setLevelId] = useState(); useEffect(() => { const ulne = Cookies.get("ulne"); setLevelId(ulne); }, []); useEffect(() => { const t = setTimeout(() => setDebouncedSearch(search), 350); return () => clearTimeout(t); }, [search]); const fetchData = useCallback(async () => { loading(); try { const req = { limit: "10", page, title: debouncedSearch, source: "", categoryId: null, search: "", sort: "desc", sortBy: "created_at", typeId, }; const res = await getArticlePagination(req as any); const payload = (res as any)?.data; const data = payload?.data ?? []; setArticles(Array.isArray(data) ? data : []); setTotalPage(payload?.meta?.totalPage ?? 1); } finally { close(); } }, [page, debouncedSearch, typeId]); useEffect(() => { fetchData(); }, [fetchData]); const getStatus = (article: any) => { if (article.isDraft) return "Draft"; if (article.publishStatus?.toLowerCase() === "cancel") return "Pending"; if (article.isPublish) return "Published"; return "Pending"; }; const statusClass = (status: string) => { const v = status.toLowerCase(); if (v === "published") return "bg-green-100 text-green-700"; if (v === "pending") return "bg-yellow-100 text-yellow-700"; if (v === "draft") return "bg-gray-200 text-gray-600"; return "bg-gray-200 text-gray-600"; }; async function handleDelete(id: number) { const ok = await Swal.fire({ icon: "warning", title: "Delete this article?", showCancelButton: true, }); if (!ok.isConfirmed) return; loading(); try { const res = await deleteArticle(String(id)); if ((res as any)?.error) { await Swal.fire({ icon: "error", title: "Delete failed", text: String((res as any)?.message ?? ""), }); return; } await fetchData(); await Swal.fire({ icon: "success", title: "Deleted", timer: 1200, showConfirmButton: false }); } finally { close(); } } const label = ARTICLE_KIND_LABEL[kind]; const basePath = articleListPath(kind); return (

News & Articles — {label}

Create and manage {label.toLowerCase()} articles. Organize with tags only.

{levelId === "3" && ( )}
{ setSearch(e.target.value); setPage(1); }} />
Article Tags Status Date Actions {articles.length > 0 ? ( articles.map((article) => ( {article.title} {article.tags || "—"} {(() => { const status = getStatus(article); return ( {status} ); })()} {formatDate(article.createdAt)} {levelId === "3" && ( )} )) ) : ( No articles yet. Create one to get started. )}

Page {page} of {totalPage}

); }