"use client" import React from "react" import { DataTable, type ActionsColumnOptions } from "@/shared/data-view/table-view" import { useResourcePage, type UseResourcePageOptions, type ResourceItem, type ResourcePageClient } from "./use-resource-page" import type { ColumnDef } from "@tanstack/react-table" export type CrudResourceColumnHelpers = { actionsColumn: (options?: Partial>>) => ColumnDef, unknown> openEdit: (row: ResourceItem) => void deleteItem: (id: string) => Promise } export type CrudResourceContext = { selectedItem: ResourceItem | null isDialogOpen: boolean dialogResourceId: string | null isLoading: boolean data: ResourceItem[] openCreate: () => void openEdit: (row: ResourceItem) => void closeDialog: () => void deleteItem: (id: string) => Promise invalidateQuery: () => void } type ReactNodeOrRender = | React.ReactNode | ((context: CrudResourceContext) => React.ReactNode) export type CrudResourceProps = UseResourcePageOptions & { columns: ColumnDef>[] | ((helpers: CrudResourceColumnHelpers) => ColumnDef>[]) onRowClick?: (row: ResourceItem) => void tableHeader?: ReactNodeOrRender render?: (table: React.ReactElement, context: CrudResourceContext) => React.ReactElement } export function CrudResource({ columns: columnsProp, routeKey, getClient, queryOptions, paramKey, extraParams, onRowClick, tableHeader, render, }: CrudResourceProps) { type TItem = ResourceItem const page = useResourcePage({ routeKey, getClient, queryOptions, paramKey, extraParams }) const columns = typeof columnsProp === "function" ? columnsProp({ actionsColumn: page.actionsColumn, openEdit: page.openEdit, deleteItem: page.deleteItem, }) : columnsProp type ListResponse = { data?: TItem[] } const responseData = page.data as ListResponse | undefined const items = (responseData?.data ?? []) as TItem[] const context: CrudResourceContext = { selectedItem: page.selectedItem, isDialogOpen: page.isDialogOpen, dialogResourceId: page.dialogResourceId, isLoading: page.isLoading, data: items, openCreate: page.openCreate, openEdit: page.openEdit, closeDialog: page.closeDialog, deleteItem: page.deleteItem, invalidateQuery: () => page.invalidateQuery(), } const table = ( <> {tableHeader && (typeof tableHeader === "function" ? tableHeader(context) : tableHeader)} ) if (render) return render(table, context) return table }