"use client"; import React, { useEffect, useState } from "react"; import { useLocal } from "@/lib/utils/use-local"; import { toast } from "sonner"; import { Loader2 } from "lucide-react"; import { ScrollArea } from "../ui/scroll-area"; import get from "lodash.get"; export const ListBetter: React.FC = ({ autoPagination = true, name, column, style = "UI", align = "center", onLoad, take = 10, header, disabledPagination, disabledHeader, disabledHeadTable, hiddenNoRow, disabledHoverRow, onInit, onCount, fm, mode, feature, onChange, content, }) => { const [data, setData] = useState([]); const [maxPage, setMaxPage] = useState(0); const [reload, setReload] = useState(0); const local = useLocal({ table: null as any, data: [] as any[], dataForm: [] as any[], listData: [] as any[], sort: {} as any, search: null as any, paging: 1, maxPage: 1, count: 0 as any, ready: false, addRow: (row: any) => { setData((prev) => [...prev, row]); local.data.push(row); local.render(); }, selection: { all: false, partial: [] as any[], data: [] as any[], }, renderRow: (row: any) => { setData((prev) => [...prev, row]); local.data = data; local.render(); }, removeRow: (row: any) => { setData((prev) => prev.filter((item) => item !== row)); // Update state lokal local.data = local.data.filter((item: any) => item !== row); // Hapus row dari local.data local.render(); // Panggil render untuk memperbarui UI }, refresh: async () => { toast.info( <> {"Loading..."} , { duration: Infinity, } ); local.ready = false; local.render(); try { if (typeof onCount === "function") { const res = await onCount(); local.count = res; local.maxPage = Math.ceil(res / take); local.paging = 1; local.render(); } if (Array.isArray(onLoad)) { let res = onLoad; local.data = res; local.render(); setData(res); } else { let res: any = await onLoad({ search: local.search, sort: local.sort, take, paging: 1, }); local.data = res; local.render(); setData(res); setTimeout(() => { toast.dismiss(); }, 100); } } catch (ex: any) { console.error(get(ex, "response.data.meta.message") || ex.message); } setTimeout(() => { toast.dismiss(); }, 100); local.ready = true; local.render(); }, reload: async () => { toast.info( <> {"Loading..."} , { duration: Infinity, } ); const listData = local.data || []; try { if (Array.isArray(onLoad)) { let res = onLoad; local.data = listData.concat(res); local.render(); setData(res); } else { let res: any = await onLoad({ search: local.search, sort: local.sort, take, paging: local.paging, }); local.data = listData.concat(res); local.render(); setData(res); setTimeout(() => { toast.dismiss(); }, 100); } } catch (ex: any) { console.error(get(ex, "response.data.meta.message") || ex.message); } setTimeout(() => { toast.dismiss(); }, 100); }, }); useEffect(() => { const run = async () => { toast.info( <> {"Loading..."} , { duration: Infinity, } ); local.ready = false; local.render(); try { if (typeof onCount === "function") { const res = await onCount(); setMaxPage(Math.ceil(res / take)); local.maxPage = Math.ceil(res / take); local.count = res; local.render(); } if (mode === "form") { local.data = fm.data?.[name] || []; local.render(); setData(fm.data?.[name] || []); } else { if (Array.isArray(onLoad)) { local.data = onLoad; local.render(); setData(onLoad); } else if (typeof onLoad === "function") { let res: any = await onLoad({ search: local.search, sort: local.sort, take, paging: 1, }); local.data = res; local.render(); setData(local.data); } else { let res = onLoad; local.data = res; local.render(); setData(local.data); } } } catch (ex: any) { console.error(get(ex, "response.data.meta.message") || ex.message); } if (typeof onInit === "function") { onInit(local); } local.ready = true; local.render(); setTimeout(() => { toast.dismiss(); }, 100); }; run(); }, []); const observerRef: any = React.useRef(); const lastPostRef = React.useCallback((node: any) => { if (observerRef) { if (observerRef.current) observerRef.current.disconnect(); observerRef.current = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { if (local.paging < local.maxPage) { local.paging = local.paging + 1; local.render(); local.reload(); setReload((r) => r + 1); } } }); if (node) observerRef.current.observe(node); } }, []); return ( <>
{!local.ready ? ( <>
) : (
{Array.isArray(local.data) && local.data?.length ? ( local.data?.map((e, idx) => { return (
{typeof content === "function" ? content({ item: e, idx, tbl: local }) : content}
); }) ) : ( <> )}
)}
); };