import { CustomerGroup } from "@medusajs/medusa" import { useAdminCustomerGroups, useAdminDeleteCustomerGroup, } from "medusa-react" import { useNavigate } from "react-router-dom" import { HeaderGroup, Row, TableInstance, TableOptions, usePagination, useSortBy, useTable, } from "react-table" import { useTranslation } from "react-i18next" import useQueryFilters from "../../../hooks/use-query-filters" import useSetSearchParams from "../../../hooks/use-set-search-params" import DetailsIcon from "../../fundamentals/details-icon" import TrashIcon from "../../fundamentals/icons/trash-icon" import { ActionType } from "../../molecules/actionables" import Table from "../../molecules/table" import TableContainer from "../../organisms/table-container" import { CUSTOMER_GROUPS_TABLE_COLUMNS } from "./config" import useNotification from "../../../hooks/use-notification" /** * Default filtering config for querying customer groups endpoint. */ const defaultQueryProps = { additionalFilters: { expand: "customers" }, limit: 15, offset: 0, } /* * Customer groups empty state. */ function CustomerGroupsPlaceholder() { return (
No customer groups yet
) } /* ******************************************** */ /* ************** TABLE ELEMENTS ************** */ /* ******************************************** */ type HeaderCellProps = { col: HeaderGroup } /* * Renders react-table cell for the customer groups table. */ function CustomerGroupsTableHeaderCell(props: HeaderCellProps) { return ( {props.col.render("Header")} ) } type HeaderRowProps = { headerGroup: HeaderGroup } /* * Renders react-table header row for the customer groups table. */ function CustomerGroupsTableHeaderRow(props: HeaderRowProps) { return ( {props.headerGroup.headers.map((col) => ( ))} ) } type CustomerGroupsTableRowProps = { row: Row } /* * Render react-table row for the customer groups table. */ function CustomerGroupsTableRow(props: CustomerGroupsTableRowProps) { const { row } = props const navigate = useNavigate() const notification = useNotification() const { mutate } = useAdminDeleteCustomerGroup(row.original.id) const { t } = useTranslation() const actions: ActionType[] = [ { label: t("customer-group-table-details", "Details"), onClick: () => navigate(row.original.id), icon: , }, { label: t("customer-group-table-delete", "Delete"), onClick: () => { mutate(undefined, { onSuccess: () => { notification( t("customer-group-table-success", "Success"), t("customer-group-table-group-deleted", "Group deleted"), "success" ) }, onError: () => { notification( t("customer-group-table-error", "Error"), t( "customer-group-table-failed-to-delete-the-group", "Failed to delete the group" ), "error" ) }, }) }, icon: , variant: "danger", }, ] return ( {props.row.cells.map((cell, index) => ( {cell.render("Cell", { index })} ))} ) } /* ******************************************** */ /* ************* TABLE CONTAINERS ************* */ /* ******************************************** */ type CustomerGroupsTableProps = ReturnType & { customerGroups: CustomerGroup[] count: number isLoading?: boolean } /* * Root component of the customer groups table. */ function CustomerGroupsTable(props: CustomerGroupsTableProps) { const { customerGroups, queryObject, count, paginate, setQuery, isLoading } = props const { t } = useTranslation() const tableConfig: TableOptions = { columns: CUSTOMER_GROUPS_TABLE_COLUMNS, data: customerGroups || [], initialState: { pageSize: queryObject.limit, pageIndex: queryObject.offset / queryObject.limit, }, pageCount: Math.ceil(count / queryObject.limit), manualPagination: true, autoResetPage: false, } const table: TableInstance = useTable( tableConfig, useSortBy, usePagination ) // ********* HANDLERS ********* const handleNext = () => { if (!table.canNextPage) { return } paginate(1) table.nextPage() } const handlePrev = () => { if (!table.canPreviousPage) { return } paginate(-1) table.previousPage() } const handleSearch = (text: string) => { setQuery(text) if (text) { table.gotoPage(0) } } // ********* RENDER ********* return ( {/* HEAD */} {table.headerGroups?.map((headerGroup, ind) => ( ))} {/* BODY */} {table.rows.map((row) => { table.prepareRow(row) return })}
) } /* * A container component for the customers group table. * Handles data fetching and query params persistence. */ function CustomerGroupsTableContainer() { const params = useQueryFilters(defaultQueryProps) const { customer_groups, isLoading, count = 0, } = useAdminCustomerGroups(params.queryObject) useSetSearchParams(params.representationObject) const showPlaceholder = !customer_groups?.length && !params.queryObject.q if (showPlaceholder) { if (!isLoading) { return } else { return null } } return ( ) } export default CustomerGroupsTableContainer