"use client"; import { Autocomplete, AutocompleteItem, BreadcrumbItem, Breadcrumbs, Button, DatePicker, Image, Input, Listbox, ListboxItem, Pagination, Popover, PopoverContent, PopoverTrigger, Select, SelectItem, } from "@heroui/react"; import { CalendarIcon, Calender, ChevronLeftIcon, ChevronRightIcon, ClockIcon, EyeFilledIcon, SearchIcon, TimesIcon, UserIcon, } from "../../icons"; import Link from "next/link"; import { useCallback, useEffect, useRef, useState } from "react"; import { getArticleByCategoryLanding, getListArticle, } from "@/services/article"; import { convertDateFormatNoTimeV2, formatMonthString, getUnixTimestamp, htmlToString, textEllipsis, } from "@/utils/global"; import { useParams, usePathname, useRouter, useSearchParams, } from "next/navigation"; import { close, loading } from "@/config/swal"; import { format } from "date-fns"; import { getCategoryById } from "@/services/master-categories"; import AsyncSelect from "react-select/async"; import { data } from "autoprefixer"; const months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; export default function ListNews() { const [article, setArticle] = useState([]); const [page, setPage] = useState(1); const router = useRouter(); const pathname = usePathname(); const [totalPage, setTotalPage] = useState(1); const topRef = useRef(null); const params = useParams(); const category = params?.name; const searchParams = useSearchParams(); const categoryIds = searchParams.get("category_id"); const [categories, setCategories] = useState([]); const [searchValue, setSearchValue] = useState( searchParams.get("search") || "", ); const [categorySearch, setCategorySearch] = useState(""); const [selectedCategoryId, setSelectedCategoryId] = useState([]); const today = new Date(); const [year, setYear] = useState(today.getFullYear()); const [selectedMonth, setSelectedMonth] = useState( searchParams.get("month") ? Number(searchParams.get("month")) - 1 : null, ); const [selectedDate, setSelectedDate] = useState(null); const [poldaCategId, setPoldaCategId] = useState(0); const isPoldaPage = pathname.includes("/news/polda/"); const [poldaCategoryOption, setPoldaCategoryOption] = useState( null, ); const requestIdRef = useRef(0); const handleMonthClick = (monthIndex: number) => { setSelectedMonth(monthIndex); setSelectedDate(new Date(year, monthIndex, 1)); }; useEffect(() => { if (isPoldaPage) getPoldaCategId(); }, [params, isPoldaPage]); const getPoldaCategId = async () => { const poldaNow = category as string; const dataNow = await getCategory(poldaNow.split("-").join(" ")); if (dataNow?.length > 0) { const poldaObj = dataNow[0]; setPoldaCategId(poldaObj.id); const option = setupCategory([poldaObj])[0]; setPoldaCategoryOption(option); setSelectedCategoryId((prev: any[]) => { const already = prev.some((x) => x.id === option.id); if (already) return prev; return [option, ...prev]; }); } }; useEffect(() => { const search = searchParams.get("search") || ""; const category = searchParams.get("category_id") || ""; const month = searchParams.get("month"); const yearQ = searchParams.get("year"); const pageQ = searchParams.get("page"); setSearchValue(search); if (pageQ) setPage(Number(pageQ)); else setPage(1); if (yearQ) setYear(Number(yearQ)); if (month && yearQ) { const m = Number(month) - 1; setSelectedMonth(m); setSelectedDate(new Date(Number(yearQ), m, 1)); } else { setSelectedMonth(null); setSelectedDate(null); } if (category && category !== "") { getCategoryFromQueries(category.split(",")); } else { setSelectedCategoryId([]); getArticle({ title: search, category: [], month: month ? Number(month) : null, year: yearQ ? Number(yearQ) : null, page: pageQ ? Number(pageQ) : 1, }); } }, [searchParams, poldaCategId]); const getCategoryFromQueries = async (category: string[]) => { const temp = []; for (const element of category) { const res = await getCategoryById(Number(element)); if (res?.data?.data) { temp.push(res?.data?.data); } } const setup = setupCategory(temp); setSelectedCategoryId(setup); const search = searchParams.get("search") || ""; const month = searchParams.get("month"); const yearQ = searchParams.get("year"); const pageQ = searchParams.get("page"); await getArticle({ title: search, category: setup, month: month ? Number(month) : null, year: yearQ ? Number(yearQ) : null, page: pageQ ? Number(pageQ) : 1, }); }; // useEffect(() => { // getArticle(); // }, [page, searchParams]); async function getArticle(props?: { title?: string; category?: any[]; month?: number | null; year?: number | null; page?: number; }) { requestIdRef.current += 1; const currentRequestId = requestIdRef.current; loading(); const usedPage = props?.page || page; const usedSearch = props?.title ?? searchValue ?? ""; const baseCategories = props?.category && props.category.length > 0 ? props.category : selectedCategoryId; let finalCategories = baseCategories; if (isPoldaPage && poldaCategId) { const hasPolda = baseCategories.some((x: any) => x.id === poldaCategId); if (!hasPolda) { finalCategories = [ ...(poldaCategoryOption ? [poldaCategoryOption] : []), ...baseCategories, ]; } } const usedCategoryIds = finalCategories.length > 0 ? finalCategories.map((val: any) => val.id).join(",") : ""; const usedMonth = props?.month ?? (selectedDate ? selectedDate.getMonth() + 1 : null); const usedYear = props?.year ?? (selectedDate ? selectedDate.getFullYear() : null); const req = { page: usedPage, search: usedSearch, limit: "9", isPublish: true, sort: "desc", categorySlug: pathname.includes("satker") ? String(category) : "", categoryIds: usedCategoryIds, startDate: usedMonth && usedYear ? convertDateFormatNoTimeV2(new Date(usedYear, usedMonth - 1, 1)) : "", endDate: usedMonth && usedYear ? convertDateFormatNoTimeV2(new Date(usedYear, usedMonth, 0)) : "", timeStamp: getUnixTimestamp(), }; try { const response = await getListArticle(req); // ❗ GUARD: hanya request terakhir yang boleh set state if (currentRequestId !== requestIdRef.current) return; setArticle(response?.data?.data); setTotalPage(response?.data?.meta?.totalPage); } finally { if (currentRequestId === requestIdRef.current) { close(); } } } const debounceTimeout = useRef(null); const getCategory = async (search?: string) => { const res = await getArticleByCategoryLanding({ // limit: debouncedValue === "" ? "5" : "", // title: debouncedValue, limit: !search || search === "" ? "5" : "", title: search ? search : "", timeStamp: getUnixTimestamp(), }); if (res?.data?.data) { setCategories(res?.data?.data); return res?.data?.data; } return []; }; const setupCategory = (data: any) => { const temp = []; for (const element of data) { temp.push({ id: element.id, label: element.title, value: element.id, }); } return temp; }; const loadOptions = useCallback( (inputValue: string, callback: (options: any) => void) => { if (debounceTimeout.current) { clearTimeout(debounceTimeout.current); } debounceTimeout.current = setTimeout(async () => { try { const data = await getCategory(inputValue); callback(setupCategory(data)); } catch (error) { callback([]); } }, 1500); }, [], ); const updateQuery = (newParams: Record) => { const params = new URLSearchParams(searchParams.toString()); Object.entries(newParams).forEach(([key, value]) => { if ( value === undefined || value === null || value === "" || (Array.isArray(value) && value.length === 0) ) { params.delete(key); } else { params.set(key, String(value)); } }); router.push(`${pathname}?${params.toString()}`); }; return (
Beranda

Berita

{ // if (event.key === "Enter") { // router.push(pathname + `?search=${searchValue}`); // getArticle(); // } // }} labelPlacement="outside" placeholder="Judul..." value={searchValue} onValueChange={setSearchValue} type="search" /> "border border-gray-300 border-1 rounded-xl min-w-[300px] max-w-[600px]", menu: () => "z-50", }} value={selectedCategoryId} onChange={(val: any) => { const nextValue = val || []; if (!pathname.includes("/news/polda/")) { setSelectedCategoryId(nextValue); return; } if (poldaCategoryOption) { const hasPolda = nextValue.some( (x: any) => x.id === poldaCategoryOption.id, ); if (!hasPolda) { setSelectedCategoryId([poldaCategoryOption, ...nextValue]); return; } } setSelectedCategoryId(nextValue); }} />
{" "} {selectedDate ? format(selectedDate, "MMMM yyyy") : "Pilih Bulan"}
{year}
{months.map((month, idx) => ( ))}
{" "} {selectedDate && ( { setSelectedDate(null); setSelectedMonth(null); updateQuery({ month: "", year: "", page: 1 }); }} > )}
{/* */} {/* */}
{article?.length < 1 || !article ? (
Tidak ada Data
) : ( <>
{article?.map((news: any) => (
thumbnail
{news?.title}

{formatMonthString(news?.createdAt)}

{`${new Date(news?.createdAt) .getHours() .toString() .padStart(2, "0")}:${new Date(news?.createdAt) .getMinutes() .toString() .padStart(2, "0")}`}

{news?.createdByName}

{textEllipsis(htmlToString(news?.description), 165)}
))}
{/* */} { setPage(p); updateQuery({ page: p }); }} classNames={{ item: "w-fit px-3", cursor: "w-fit px-3", }} />
)}
); }