// modules/admin/pages/advertisements/AdvertisementList.jsx
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { House, Plus, Search, Megaphone, MousePointerClick, Edit, Trash2, Archive } from "lucide-react";
import { useAdvertisements } from "@/contexts/AdminAdvertisementContext";
import { resolveAssetSrc } from "@/utils/media.util";
import AppBreadcrumb from "@/components/generic/Breadcrumb/AppBreadcrumb";
import { useDateFormat } from "@/hooks/useDateFormat";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Spinner } from "@/components/ui/spinner";
import {
AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { ADVERTISEMENT_TYPES, ADVERTISEMENT_TYPE_MAP, ADVERTISEMENT_FILTERABLE_STATUSES, ADVERTISEMENT_STATUS_MAP } from "@/data/advertisement.data";
import { PLACEMENT_MAP } from "@/data/placement.data";
import { TablePagination } from "@/components/generic/Table/TablePagination";
const DEFAULT_PAGE_SIZE = 10;
export default function AdvertisementList() {
const navigate = useNavigate();
const { advertisements, pagination, loading, fetchAdvertisements, archiveAdvertisement } = useAdvertisements();
const [typeFilter, setTypeFilter] = useState("all");
const [statusFilter, setStatusFilter] = useState("all");
const [searchInput, setSearchInput] = useState("");
const [search, setSearch] = useState("");
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
const buildFilters = () => {
const filters = [];
if (typeFilter !== "all") filters.push({ id: "type", value: typeFilter });
if (statusFilter !== "all") filters.push({ id: "status", value: statusFilter });
if (search.trim()) filters.push({ id: "headline", value: search.trim() });
return filters;
};
// Single source of truth for fetching — filter setters below always pair
// their state update with setPage(1) in the same handler so this only
// ever fires once per change (no separate "reset page" effect racing it).
useEffect(() => {
fetchAdvertisements({ page, limit: pageSize, filters: buildFilters() });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [typeFilter, statusFilter, search, page, pageSize]);
const handleTypeFilter = (v) => { setTypeFilter(v); setPage(1); };
const handleStatusFilter = (v) => { setStatusFilter(v); setPage(1); };
const runSearch = () => { setSearch(searchInput); setPage(1); };
const handlePageSizeChange = (size) => { setPageSize(size); setPage(1); };
const items = [
{ label: "Home", icon: Manage public-facing hero and banner placementsAdvertisements
{label}
{value}
No advertisements yet
Create your first hero or banner placement.