All files / src/features/Events/EventDetail/hooks useEventTransactions.ts

89.47% Statements 17/19
100% Branches 6/6
71.42% Functions 5/7
94.44% Lines 17/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                        1x                 1x 6x 6x       6x 9x   6x 9x             6x     6x   6x   6x                                         6x 3x     6x 2x       6x                          
import { useEffect, useMemo } from "react";
import { QKEY_EVENT_TRANSACTIONS } from "@constants/queryKeys";
import { useAppSelector } from "@redux/hooks";
import { sortingKey } from "@redux/slices/fundraisers";
import { selectQueryString } from "@redux/slices/search";
import { useGetTransactionsByProduct } from "@services/api/products/transactions";
import { useFormattedFilters } from "@shared/GiveFilter/hooks/useFormattedFilters";
import { usePagination } from "@hooks/common/usePagination";
import { useParseTransactionRow } from "@pages/FundraisersDonationList/utils";
import { useRowsPerPage } from "componentsV2/Table/hooks/useRowsPerPage";
import { STORED_EVENT_TRANSACTIONS_ROWS_PER_PAGE } from "../constants";
 
const DEFAULT_SORTING = "-createdAt";
 
/**
 * PayBuilder 032-b AC006 — server state for the Event Detail transactions tab.
 *
 * Search (AC006.5), the date filter, page + rows-per-page (AC006.6) and Date
 * sorting (AC006.1) are all query inputs, so every one of them refetches
 * rather than filtering an already-loaded page.
 */
export const useEventTransactions = (eventId?: string) => {
  const { rowParser } = useParseTransactionRow();
  const { rowsPerPage } = useRowsPerPage(
    STORED_EVENT_TRANSACTIONS_ROWS_PER_PAGE,
  );
 
  const searchQuery = useAppSelector((state) =>
    selectQueryString(state, QKEY_EVENT_TRANSACTIONS),
  );
  const sorting = useAppSelector((state) =>
    sortingKey(state, QKEY_EVENT_TRANSACTIONS),
  );
 
  // The filter panel (FilterPagesEnum.EVENT_TRANSACTIONS) writes its fql string
  // into the dynamic filter slice under this same query key — the same wiring the
  // Tickets tab uses. It replaced the date-only popover that wrote into the
  // transactions slice.
  const { formattedFilterString } = useFormattedFilters({
    queryKey: QKEY_EVENT_TRANSACTIONS,
  });
  const queryString = formattedFilterString;
 
  const { page, setPage } = usePagination(0, searchQuery);
 
  const { data, isLoading, isFetching, error } = useGetTransactionsByProduct(
    eventId as string,
    QKEY_EVENT_TRANSACTIONS,
  )(
    {
      page,
      sorting: sorting || DEFAULT_SORTING,
      searchQuery,
      queryString,
      maxRowsPerPage: rowsPerPage,
    },
    {
      enabled: Boolean(eventId),
      refetchOnWindowFocus: false,
      keepPreviousData: true,
    },
  );
 
  // A changed filter, page size or sort order can leave us on a page that no
  // longer exists — go back to the first one rather than showing an empty
  // table.
  useEffect(() => {
    setPage(1);
  }, [searchQuery, sorting, rowsPerPage, queryString]);
 
  const allRows = useMemo(
    () => (data?.data ?? []).map(rowParser),
    [data?.data],
  );
 
  return {
    allRows,
    totalRows: data?.total ?? 0,
    rowsPerPage,
    page,
    setPage: () => setPage((current) => current + 1),
    setPageDispatcher: setPage,
    isLoading,
    isFetching,
    isError: Boolean(error),
    searchQuery,
  };
};