Files
starr-philproperties/src/modules/admin/components/tiers/ArchivedTierPlansTable.jsx
T
2026-07-21 09:52:04 +08:00

189 lines
6.1 KiB
React

import { useMemo, useRef, useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useTiers } from "@/contexts/AdminTiersContext";
import { useAuth } from "@/contexts/AuthContext";
import DataTable from "@/components/generic/Table/DataTable";
import { FilterSheet } from "@/components/generic/Sheet/FilterSheet";
import { RestoreDialog } from "@/components/generic/Dialogs/RestoreDialog";
import { PermanentDeleteDialog } from "@/components/generic/Dialogs/PermanentDeleteDialog";
import { buildDataColumns, columnPinning } from "../../config/tiers/plans/archive/columns.config";
import { buildToolbarActions } from "../../config/tiers/plans/archive/toolbar.config";
import { buildSelectionActions } from "../../config/tiers/plans/archive/selection.config";
import { buildRowActions } from "../../config/tiers/plans/archive/rowActions.config";
import { getTimestamp } from "@/utils/timestamp.util";
import { formatGeneratedBy } from "@/utils/generatedBy.util";
export default function ArchivedTierPlansTable() {
const navigate = useNavigate();
const { user: currentUser } = useAuth();
const {
plans, planAttributes, planPagination, setPlanPagination,
loading, fetchPlans, restorePlan, bulkRestorePlans,
permanentlyDeletePlan, bulkPermanentlyDeletePlans, fetchPlanPermanentDeleteImpact,
} = useTiers();
const [restoreTarget, setRestoreTarget] = useState(null);
const [restoreIds, setRestoreIds] = useState(null);
const [deleteTarget, setDeleteTarget] = useState(null);
const [deleteIds, setDeleteIds] = useState(null);
const tableRefsRef = useRef({
getFilters: () => [],
getSort: () => [],
resetSelection: () => {},
tableInstance: null,
});
const handleRefsReady = (refs) => { tableRefsRef.current = refs; };
const fetchArchived = useCallback(
(params) => fetchPlans({ ...params, archived: true }),
[fetchPlans]
);
const exportConfig = useMemo(() => ({
allData: plans,
attributes: planAttributes,
filename: `${getTimestamp()}_ArchivedTierPlans`,
sheetName: "Archived Tier Plans",
generatedBy: formatGeneratedBy(currentUser),
}), [plans, planAttributes, currentUser]);
const rowActions = buildRowActions({
navigate,
onRestore: (row) => setRestoreTarget(row),
onDelete: (row) => setDeleteTarget(row),
});
const toolbarActions = buildToolbarActions({
fetchPlans: fetchArchived,
pagination: planPagination,
exportConfig,
navigate,
getFilters: () => tableRefsRef.current.getFilters(),
getSort: () => tableRefsRef.current.getSort(),
getTableInstance: () => tableRefsRef.current.tableInstance,
});
const selectionActions = buildSelectionActions({
exportConfig,
onRestore: (row) => setRestoreTarget(row),
onRestoreMany: (ids) => setRestoreIds(ids),
onDelete: (row) => setDeleteTarget(row),
onDeleteMany: (ids) => setDeleteIds(ids),
getTableInstance: () => tableRefsRef.current.tableInstance,
});
const columns = useMemo(
() => buildDataColumns(planAttributes, rowActions),
[planAttributes, rowActions]
);
const handleRestoreSuccess = () => {
setRestoreTarget(null);
setRestoreIds(null);
tableRefsRef.current.resetSelection?.();
fetchArchived({
page: 1,
limit: planPagination?.limit ?? 10,
filters: tableRefsRef.current.getFilters(),
sort: tableRefsRef.current.getSort(),
});
};
const handleDeleteSuccess = () => {
setDeleteTarget(null);
setDeleteIds(null);
tableRefsRef.current.resetSelection?.();
fetchArchived({
page: 1,
limit: planPagination?.limit ?? 10,
filters: tableRefsRef.current.getFilters(),
sort: tableRefsRef.current.getSort(),
});
};
return (
<>
<DataTable
title="Archived Plans"
data={plans}
columns={columns}
attributes={planAttributes}
pagination={planPagination}
setPagination={setPlanPagination}
loading={loading}
onFetch={fetchArchived}
onFetchFilterData={async () => []}
onRefsReady={handleRefsReady}
renderFilterSheet={({ open, onOpenChange, column, attr, data, loading }) => (
<FilterSheet
open={open}
onOpenChange={onOpenChange}
column={column}
attr={attr}
data={data}
loading={loading}
/>
)}
columnPinning={columnPinning}
toolbarActions={toolbarActions}
selectionActions={selectionActions}
recordLabel="plan"
emptyMessage="No archived plans found."
/>
<RestoreDialog
open={!!restoreTarget}
onOpenChange={(v) => !v && setRestoreTarget(null)}
entity={restoreTarget}
entityLabel="Plan"
getName={(r) => r?.label}
onRestore={(entity) => restorePlan(entity?.plan_id)}
loading={loading}
onSuccess={handleRestoreSuccess}
/>
<RestoreDialog
open={!!restoreIds}
onOpenChange={(v) => !v && setRestoreIds(null)}
ids={restoreIds ?? []}
entityLabel="Plan"
onRestore={({ ids }) => bulkRestorePlans(ids)}
loading={loading}
onSuccess={handleRestoreSuccess}
/>
{/* Single permanent delete */}
<PermanentDeleteDialog
open={!!deleteTarget}
onOpenChange={(v) => !v && setDeleteTarget(null)}
entity={deleteTarget}
entityLabel="Plan"
getName={(r) => r?.label}
onDelete={(entity) => permanentlyDeletePlan(entity?.plan_id)}
onImpactCheck={() => fetchPlanPermanentDeleteImpact(deleteTarget?.plan_id)}
loading={loading}
onSuccess={handleDeleteSuccess}
/>
{/* Bulk permanent delete */}
<PermanentDeleteDialog
open={!!deleteIds}
onOpenChange={(v) => !v && setDeleteIds(null)}
ids={deleteIds ?? []}
entityLabel="Plan"
onDelete={({ ids }) => bulkPermanentlyDeletePlans(ids)}
loading={loading}
onSuccess={handleDeleteSuccess}
/>
</>
);
}