update filter table, ui dashboard
continuous-integration/drone/push Build encountered an error Details

This commit is contained in:
Anang Yusman 2026-03-16 16:08:49 +08:00
parent a698dfa52a
commit 165ccdb718
7 changed files with 431 additions and 106 deletions

View File

@ -63,8 +63,8 @@ export default function ImageFilterPage() {
<FloatingMenuNews />
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
{Array.from({ length: 6 }).map((_, i) => (
<div className="">
{Array.from({ length: 1 }).map((_, i) => (
<ImageCard key={i} />
))}
</div>

View File

@ -2,50 +2,97 @@
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import { getListArticle } from "@/service/article";
type Article = {
id: number;
title: string;
description: string;
categoryName: string;
createdAt: string;
slug: string;
thumbnailUrl?: string;
};
export default function ImageCard() {
const slug = "bharatu-mardi-hadji-gugur-saat-bertugas";
const [articles, setArticles] = useState<Article[]>([]);
const [page] = useState(1);
const [showData] = useState("6");
const [search] = useState("");
async function initState() {
const req = {
limit: showData,
page,
search,
categorySlug: "",
sort: "desc",
isPublish: true,
sortBy: "created_at",
};
try {
const res = await getListArticle(req);
setArticles(res?.data?.data || []);
} catch (err) {
console.error("Error get article:", err);
}
}
useEffect(() => {
initState();
}, []);
return (
<Link href={`/details/${slug}?type=image`}>
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm hover:shadow-md transition duration-300 overflow-hidden">
{/* IMAGE */}
<div className="relative h-[200px] w-full">
<Image
src="/image/novita2.png"
alt="news"
fill
className="object-cover"
/>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{articles.map((item) => (
<Link key={item.id} href={`/details/${item.slug}?type=image`}>
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm hover:shadow-md transition duration-300 overflow-hidden">
{/* IMAGE */}
<div className="relative h-[200px] w-full">
<Image
src={item.thumbnailUrl || "/image/novita2.png"}
alt={item.title}
fill
className="object-cover"
/>
</div>
{/* CONTENT */}
<div className="p-5 space-y-3">
{/* BADGE + TAG */}
<div className="flex items-center gap-2 text-xs">
<span className="bg-red-600 text-white px-2 py-[3px] rounded-md font-medium">
POLRI
</span>
<span className="text-gray-500 uppercase tracking-wide">
SEPUTAR PRESTASI
</span>
{/* CONTENT */}
<div className="p-5 space-y-3">
{/* BADGE + TAG */}
<div className="flex items-center gap-2 text-xs">
<span className="bg-red-600 text-white px-2 py-[3px] rounded-md font-medium">
POLRI
</span>
<span className="text-gray-500 uppercase tracking-wide">
{item.categoryName}
</span>
</div>
{/* DATE */}
<p className="text-xs text-gray-400">
{new Date(item.createdAt).toLocaleDateString("id-ID", {
day: "2-digit",
month: "long",
year: "numeric",
})}
</p>
{/* TITLE */}
<h3 className="font-semibold text-[15px] leading-snug line-clamp-2 hover:text-[#966314] transition">
{item.title}
</h3>
{/* EXCERPT */}
<p className="text-sm text-gray-500 line-clamp-2 leading-relaxed">
{item.description}
</p>
</div>
</div>
{/* DATE */}
<p className="text-xs text-gray-400">02 Februari 2024</p>
{/* TITLE */}
<h3 className="font-semibold text-[15px] leading-snug line-clamp-2 hover:text-[#966314] transition">
Bharatu Mardi Hadji Gugur Saat Bertugas, Diganjar Kenaikan Pangkat
Luar Biasa
</h3>
{/* EXCERPT */}
<p className="text-sm text-gray-500 line-clamp-2 leading-relaxed">
Jakarta - Kapolri Jenderal Polisi Drs. Listyo Sigit Prabowo
memberikan kenaikan pangkat luar biasa anumerta kepada...
</p>
</div>
</div>
</Link>
</Link>
))}
</div>
);
}

View File

@ -31,7 +31,7 @@ const Option = ({
onMouseLeave={() => setHovered(false)}
className={`relative flex h-12 w-full px-3 items-center rounded-xl transition-all duration-200 cursor-pointer group ${
isActive
? "bg-gradient-to-r from-[#966314] to-[#966314] text-white shadow-lg shadow-emerald-500/25"
? "bg-gradient-to-r from-[#966314] to-[#966314] text-white shadow-xl shadow-[#9663144D]/25"
: "text-slate-600 hover:bg-gradient-to-r hover:from-slate-100 hover:to-slate-200/50 hover:text-slate-800"
}`}
whileHover={{ scale: 1.02 }}

View File

@ -344,24 +344,88 @@ export default function DashboardContainer() {
value: 24,
growth: "+12%",
iconBg: "bg-blue-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
>
<path d="M15 2.5V4c0 1.414 0 2.121.44 2.56C15.878 7 16.585 7 18 7h1.5"></path>
<path d="M4 16V8c0-2.828 0-4.243.879-5.121C5.757 2 7.172 2 10 2h4.172c.408 0 .613 0 .797.076c.183.076.328.22.617.51l3.828 3.828c.29.29.434.434.51.618c.076.183.076.388.076.796V16c0 2.828 0 4.243-.879 5.121C18.243 22 16.828 22 14 22h-4c-2.828 0-4.243 0-5.121-.879C4 20.243 4 18.828 4 16m4-5h8m-8 3h8m-8 3h4.17"></path>
</g>
</svg>
),
},
{
title: "Pending Approval",
value: 8,
growth: "+3",
iconBg: "bg-yellow-500",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g fill="none">
<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"
></path>
</g>
</svg>
),
},
{
title: "Published",
value: 16,
growth: "+5",
iconBg: "bg-green-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M10.5 15.25A.74.74 0 0 1 10 15l-3-3a.75.75 0 0 1 1-1l2.47 2.47L19 5a.75.75 0 0 1 1 1l-9 9a.74.74 0 0 1-.5.25"
></path>
<path
fill="currentColor"
d="M12 21a9 9 0 0 1-7.87-4.66a8.7 8.7 0 0 1-1.07-3.41a9 9 0 0 1 4.6-8.81a8.7 8.7 0 0 1 3.41-1.07a8.9 8.9 0 0 1 3.55.34a.75.75 0 1 1-.43 1.43a7.6 7.6 0 0 0-3-.28a7.4 7.4 0 0 0-2.84.89a7.5 7.5 0 0 0-2.2 1.84a7.42 7.42 0 0 0-1.64 5.51a7.4 7.4 0 0 0 .89 2.84a7.5 7.5 0 0 0 1.84 2.2a7.42 7.42 0 0 0 5.51 1.64a7.4 7.4 0 0 0 2.84-.89a7.5 7.5 0 0 0 2.2-1.84a7.42 7.42 0 0 0 1.64-5.51a.75.75 0 1 1 1.57-.15a9 9 0 0 1-4.61 8.81A8.7 8.7 0 0 1 12.93 21z"
></path>
</svg>
),
},
{
title: "Rejected",
value: 2,
growth: "-1",
iconBg: "bg-red-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="m12 13.4l2.9 2.9q.275.275.7.275t.7-.275t.275-.7t-.275-.7L13.4 12l2.9-2.9q.275-.275.275-.7t-.275-.7t-.7-.275t-.7.275L12 10.6L9.1 7.7q-.275-.275-.7-.275t-.7.275t-.275.7t.275.7l2.9 2.9l-2.9 2.9q-.275.275-.275.7t.275.7t.7.275t.7-.275zm0 8.6q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"
></path>
</svg>
),
},
];
@ -406,20 +470,25 @@ export default function DashboardContainer() {
{stats.map((card, i) => (
<div
key={i}
className="bg-white rounded-2xl shadow border p-6 flex justify-between items-start"
className="bg-white rounded-2xl shadow border p-6 flex-row items-start"
>
<div>
<p className="text-sm text-slate-500">{card.title}</p>
<h2 className="text-3xl font-bold text-slate-800 mt-2">
{card.value}
</h2>
</div>
<div className="flex flex-row items-center justify-between">
<div
className={`w-10 h-10 rounded-xl flex items-center justify-center text-white ${card.iconBg}`}
>
{card.icon}
</div>
<div className="text-right">
<p className="text-sm text-green-600 font-medium">
{card.growth}
</p>
<div className={`w-10 h-10 rounded-xl mt-3 ${card.iconBg}`} />
</div>
<div>
<h2 className="text-3xl font-bold text-slate-800 mt-2">
{card.value}
</h2>
<p className="text-sm text-slate-500">{card.title}</p>
</div>
</div>
))}
@ -473,19 +542,19 @@ export default function DashboardContainer() {
<div className="bg-[#966314] rounded-2xl shadow p-6 text-white space-y-4">
<h2 className="text-lg font-semibold">Quick Actions</h2>
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-xl text-sm font-medium">
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-md text-sm font-medium text-start pl-3">
+ Create New Article
</button>
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-xl text-sm font-medium">
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-md text-sm font-medium text-start pl-3">
+ Update Product
</button>
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-xl text-sm font-medium">
<button className="w-full border border-white bg-[#966314] hover:bg-[#966314] transition py-3 rounded-md text-sm font-medium text-start pl-3">
+ Upload Media
</button>
<button className="w-full bg-white text-amber-800 py-3 rounded-xl text-sm font-semibold">
<p className="border-b-2" />
<button className="w-full bg-[#EBE2D2] text-amber-800 py-3 rounded-md text-sm font-semibold ">
View All Actions
</button>
</div>
@ -500,25 +569,89 @@ export default function DashboardContainer() {
title: "Pending Review",
value: 12,
growth: "+3",
color: "bg-yellow-500",
iconBg: "bg-yellow-500",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g fill="none">
<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"
></path>
</g>
</svg>
),
},
{
title: "Approved Today",
value: 8,
growth: "+5",
color: "bg-green-600",
iconBg: "bg-green-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M10.5 15.25A.74.74 0 0 1 10 15l-3-3a.75.75 0 0 1 1-1l2.47 2.47L19 5a.75.75 0 0 1 1 1l-9 9a.74.74 0 0 1-.5.25"
></path>
<path
fill="currentColor"
d="M12 21a9 9 0 0 1-7.87-4.66a8.7 8.7 0 0 1-1.07-3.41a9 9 0 0 1 4.6-8.81a8.7 8.7 0 0 1 3.41-1.07a8.9 8.9 0 0 1 3.55.34a.75.75 0 1 1-.43 1.43a7.6 7.6 0 0 0-3-.28a7.4 7.4 0 0 0-2.84.89a7.5 7.5 0 0 0-2.2 1.84a7.42 7.42 0 0 0-1.64 5.51a7.4 7.4 0 0 0 .89 2.84a7.5 7.5 0 0 0 1.84 2.2a7.42 7.42 0 0 0 5.51 1.64a7.4 7.4 0 0 0 2.84-.89a7.5 7.5 0 0 0 2.2-1.84a7.42 7.42 0 0 0 1.64-5.51a.75.75 0 1 1 1.57-.15a9 9 0 0 1-4.61 8.81A8.7 8.7 0 0 1 12.93 21z"
></path>
</svg>
),
},
{
title: "Total Published",
value: 156,
growth: "+12%",
color: "bg-blue-600",
iconBg: "bg-blue-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
>
<path d="M15 2.5V4c0 1.414 0 2.121.44 2.56C15.878 7 16.585 7 18 7h1.5"></path>
<path d="M4 16V8c0-2.828 0-4.243.879-5.121C5.757 2 7.172 2 10 2h4.172c.408 0 .613 0 .797.076c.183.076.328.22.617.51l3.828 3.828c.29.29.434.434.51.618c.076.183.076.388.076.796V16c0 2.828 0 4.243-.879 5.121C18.243 22 16.828 22 14 22h-4c-2.828 0-4.243 0-5.121-.879C4 20.243 4 18.828 4 16m4-5h8m-8 3h8m-8 3h4.17"></path>
</g>
</svg>
),
},
{
title: "Rejected",
value: 5,
growth: "-1",
color: "bg-red-600",
iconBg: "bg-red-600",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="m12 13.4l2.9 2.9q.275.275.7.275t.7-.275t.275-.7t-.275-.7L13.4 12l2.9-2.9q.275-.275.275-.7t-.275-.7t-.7-.275t-.7.275L12 10.6L9.1 7.7q-.275-.275-.7-.275t-.7.275t-.275.7t.275.7l2.9 2.9l-2.9 2.9q-.275.275-.275.7t.275.7t.7.275t.7-.275zm0 8.6q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"
></path>
</svg>
),
},
];
@ -544,16 +677,66 @@ export default function DashboardContainer() {
status: "Approved",
title: "Technology Summit Event",
time: "10 mins ago",
iconBg: "bg-[#DCFCE7]",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g fill="currentColor">
<path d="M10.243 16.314L6 12.07l1.414-1.414l2.829 2.828l5.656-5.657l1.415 1.415z"></path>
<path
fillRule="evenodd"
d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12m11 9a9 9 0 1 1 0-18a9 9 0 0 1 0 18"
clipRule="evenodd"
></path>
</g>
</svg>
),
},
{
status: "Rejected",
title: "Product Update Draft",
time: "25 mins ago",
iconBg: "bg-[#FFE2E2]",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="m12 13.4l2.9 2.9q.275.275.7.275t.7-.275t.275-.7t-.275-.7L13.4 12l2.9-2.9q.275-.275.275-.7t-.275-.7t-.7-.275t-.7.275L12 10.6L9.1 7.7q-.275-.275-.7-.275t-.7.275t-.275.7t.275.7l2.9 2.9l-2.9 2.9q-.275.275-.275.7t.275.7t.7.275t.7-.275zm0 8.6q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"
></path>
</svg>
),
},
{
status: "Approved",
title: "Partner Logo Update",
time: "1 hour ago",
iconBg: "bg-[#DCFCE7]",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={25}
height={25}
viewBox="0 0 24 24"
>
<g fill="currentColor">
<path d="M10.243 16.314L6 12.07l1.414-1.414l2.829 2.828l5.656-5.657l1.415 1.415z"></path>
<path
fillRule="evenodd"
d="M1 12C1 5.925 5.925 1 12 1s11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12m11 9a9 9 0 1 1 0-18a9 9 0 0 1 0 18"
clipRule="evenodd"
></path>
</g>
</svg>
),
},
];
@ -574,20 +757,25 @@ export default function DashboardContainer() {
{stats.map((card, i) => (
<div
key={i}
className="bg-white rounded-2xl shadow border p-6 flex justify-between items-start"
className="bg-white rounded-2xl shadow border p-6 flex flex-col"
>
<div>
<p className="text-sm text-slate-500">{card.title}</p>
<h2 className="text-3xl font-bold text-slate-800 mt-2">
{card.value}
</h2>
</div>
<div className="flex flex-row items-center justify-between">
<div
className={`w-10 h-10 rounded-md flex items-center justify-center text-white ${card.iconBg}`}
>
{card.icon}
</div>
<div className="text-right">
<p className="text-sm text-green-600 font-medium">
{card.growth}
</p>
<div className={`w-10 h-10 rounded-xl mt-3 ${card.color}`} />
</div>
<div>
<h2 className="text-3xl font-bold text-slate-800 mt-2">
{card.value}
</h2>
<p className="text-sm text-slate-500">{card.title}</p>
</div>
</div>
))}
@ -656,18 +844,27 @@ export default function DashboardContainer() {
key={i}
className="border rounded-xl p-4 flex justify-between items-center"
>
<div>
<p
className={`text-sm font-medium ${
item.status === "Approved"
? "text-green-600"
: "text-red-600"
}`}
<div className="flex flex-row items-center gap-3">
<div
className={`w-10 h-10 rounded-md flex items-center justify-center
${item.status === "Approved" ? "text-green-600" : "text-red-600"}
${item.iconBg}`}
>
{item.status}
</p>
<p className="text-sm text-slate-700">{item.title}</p>
<p className="text-xs text-slate-500">{item.time}</p>
{item.icon}
</div>
<div>
<p
className={`text-sm font-medium ${
item.status === "Approved"
? "text-green-600"
: "text-red-600"
}`}
>
{item.status}
</p>
<p className="text-sm text-slate-700">{item.title}</p>
<p className="text-xs text-slate-500">{item.time}</p>
</div>
</div>
</div>
))}

View File

@ -15,7 +15,7 @@ import {
} from "@/components/ui/table";
import { Search, Filter, Eye, Pencil, Trash2, Plus } from "lucide-react";
import Link from "next/link";
import { getArticlePagination } from "@/service/article";
import { getArticleByCategory, getArticlePagination } from "@/service/article";
import { formatDate } from "@/utils/global";
import { close, loading } from "@/config/swal";
import Cookies from "js-cookie";
@ -26,15 +26,28 @@ export default function NewsImage() {
const [totalPage, setTotalPage] = useState(1);
const [search, setSearch] = useState("");
const [levelId, setLevelId] = useState<string | undefined>();
const [categories, setupCategory] = useState<any[]>([]);
const [selectedCategory, setSelectedCategory] = useState<number | null>(null);
useEffect(() => {
const ulne = Cookies.get("ulne");
setLevelId(ulne);
}, []);
useEffect(() => {
fetchCategory();
}, []);
const fetchCategory = async () => {
const res = await getArticleByCategory();
if (res?.data?.data) {
setupCategory(res.data.data);
}
};
useEffect(() => {
fetchData();
}, [page, search]);
}, [page, search, selectedCategory]);
async function fetchData() {
loading();
@ -42,12 +55,13 @@ export default function NewsImage() {
const req = {
limit: "10",
page: page,
search: search,
source: "internal", // jika ingin filter image/internal
title: search,
source: "internal",
categoryId: selectedCategory,
search: "",
sort: "desc",
sortBy: "created_at",
};
const res = await getArticlePagination(req);
const data = res?.data?.data || [];
@ -58,8 +72,20 @@ export default function NewsImage() {
close();
}
const getStatus = (article: any) => {
if (article.isDraft) return "Draft";
if (article.publishStatus?.toLowerCase() === "cancel") {
return "Pending";
}
if (article.isPublish) return "Published";
return "Pending";
};
const statusVariant = (status: string) => {
const value = status?.toLowerCase();
const value = status.toLowerCase();
if (value === "published") {
return "bg-green-100 text-green-700";
@ -69,13 +95,26 @@ export default function NewsImage() {
return "bg-yellow-100 text-yellow-700";
}
if (value === "cancel") {
return "bg-red-100 text-red-700";
if (value === "draft") {
return "bg-gray-200 text-gray-600";
}
return "bg-gray-200 text-gray-600";
};
const getCategoryCount = (title: string) => {
return articles.filter((article) =>
article.categories?.some((c: any) => c.title === title),
).length;
};
const filteredArticles =
selectedCategory === null
? articles
: articles.filter((article) =>
article.categories?.some((c: any) => c.id === selectedCategory),
);
return (
<div className="space-y-6">
{/* ================= HEADER ================= */}
@ -97,7 +136,42 @@ export default function NewsImage() {
</Link>
)}
</div>
<div className="flex flex-wrap gap-2">
<Button
size="sm"
variant={selectedCategory === null ? "default" : "outline"}
onClick={() => {
setSelectedCategory(null);
setPage(1);
}}
>
<div className="flex items-center gap-1">
All
<span className="text-xs bg-slate-200 px-2 py-0.5 rounded-full">
{articles.length}
</span>
</div>
</Button>
{categories.map((cat: any) => (
<Button
key={cat.id}
size="sm"
variant={selectedCategory === cat.id ? "default" : "outline"}
onClick={() => {
setSelectedCategory(cat.id);
setPage(1);
}}
>
<div className="flex items-center gap-1">
{cat.title}
<span className="text-xs bg-white text-black px-2 py-0.5 rounded-full ">
{getCategoryCount(cat.title)}
</span>
</div>
</Button>
))}
</div>
{/* ================= SEARCH ================= */}
<div className="flex gap-3">
<div className="relative flex-1">
@ -121,7 +195,7 @@ export default function NewsImage() {
<Table>
<TableHeader>
<TableRow>
<TableHead>Article</TableHead>
<TableHead className="pl-3">Article</TableHead>
<TableHead>Category</TableHead>
<TableHead>Author</TableHead>
<TableHead>Status</TableHead>
@ -131,10 +205,10 @@ export default function NewsImage() {
</TableHeader>
<TableBody>
{articles.length > 0 ? (
articles.map((article, index) => (
{filteredArticles.length > 0 ? (
filteredArticles.map((article, index) => (
<TableRow key={article.id}>
<TableCell className="font-medium max-w-xs">
<TableCell className="font-medium max-w-xs pl-3">
{article.title}
</TableCell>
@ -151,13 +225,19 @@ export default function NewsImage() {
</TableCell>
<TableCell>
<span
className={`px-3 py-1 text-xs rounded-full font-medium ${statusVariant(
article.publishStatus,
)}`}
>
{article.publishStatus}
</span>
{(() => {
const status = getStatus(article);
return (
<span
className={`px-3 py-1 text-xs rounded-full font-medium ${statusVariant(
status,
)}`}
>
{status}
</span>
);
})()}
</TableCell>
<TableCell>{formatDate(article.createdAt)}</TableCell>

View File

@ -22,7 +22,7 @@ export async function getListArticle(props: PaginationRequest) {
isBanner,
} = props;
return await httpGet(
return await httpGetInterceptor(
`/articles?limit=${limit}&page=${page}&isPublish=${
isPublish === undefined ? "" : isPublish
}&title=${search}&startDate=${startDate || ""}&endDate=${
@ -30,7 +30,6 @@ export async function getListArticle(props: PaginationRequest) {
}&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
sort || "desc"
}&category=${categorySlug || ""}&isBanner=${isBanner || ""}`,
null,
);
}
@ -38,10 +37,10 @@ export async function getArticlePagination(props: PaginationRequest) {
const {
page,
limit,
search,
title,
startDate,
endDate,
category,
categoryId,
sortBy,
sort,
categorySlug,
@ -51,9 +50,9 @@ export async function getArticlePagination(props: PaginationRequest) {
} = props;
return await httpGet(
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${
`/articles?limit=${limit}&page=${page}&title=${title || ""}&startDate=${
startDate || ""
}&endDate=${endDate || ""}&categoryId=${category || ""}&source=${
}&endDate=${endDate || ""}&categoryId=${categoryId || ""}&source=${
source || ""
}&isPublish=${isPublish !== undefined ? isPublish : ""}&sortBy=${
sortBy || "created_at"

View File

@ -306,6 +306,8 @@ export type PaginationRequest = {
search: string;
startDate?: string;
endDate?: string;
categoryId: any;
title: string;
isPublish?: boolean;
category?: string;
sortBy?: string;