Загрузка данных


import { DEFAULT_TABLE_PAGINATION_LIMIT } from '@/shared/consts/constants';
import {
  DeviceType,
  SortType,
  useGetControllerTypeV2Query,
  useGetDeviceTypeV2Query,
  useGetPadletTypesQuery,
} from '@shared/api/controller/client';
import { useSetDrawerType } from '@shared/hooks/drawer/useSetDrawerType';
import { DrawerType, DrawerTypes } from '@shared/model/drawer/drawer.types';
import { SettingsPageTypes } from '@widgets/Settings/types';

import { ChangeEvent, MouseEvent, useEffect, useState } from 'react';

const updateDrawerTypes = new Map([
  [SettingsPageTypes.device, DrawerTypes.updateDeviceType],
  [SettingsPageTypes.controller, DrawerTypes.updateControllerType],
  [SettingsPageTypes.padlet, DrawerTypes.updatePadletType],
]);

type Props = {
  pageType: SettingsPageTypes;
  searchName?: string;
};

const DEFAULT_PAGE = 1;

export const useTypeTableState = ({ pageType, searchName }: Props) => {
  const setDrawerType = useSetDrawerType();

  const [page, setPage] = useState(DEFAULT_PAGE);
  const [sortType, setSortType] = useState<SortType>('asc');
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  const [type, setType] = useState<DeviceType | undefined>(undefined);
  const [customPageValue, setCustomPageValue] = useState(String(DEFAULT_PAGE));

  const offset = page > 0 ? (page - 1) * DEFAULT_TABLE_PAGINATION_LIMIT : 0;

  const handleSortTypeChange = (e: MouseEvent<HTMLElement>) => {
    // @ts-ignore
    setSortType(e.target.dataset.value as SortType);
  };

  const { data: deviceData, isFetching: isDeviceDataFetching } =
    useGetDeviceTypeV2Query(
      {
        sortColumn: 'name',
        sortType,
        limit: DEFAULT_TABLE_PAGINATION_LIMIT,
        offset,
        name: searchName,
      },
      { skip: pageType !== SettingsPageTypes.device },
    );

  const { data: controllerData, isFetching: isControllerDataFetching } =
    useGetControllerTypeV2Query(
      {
        sortColumn: 'name',
        sortType,
        limit: DEFAULT_TABLE_PAGINATION_LIMIT,
        offset,
        name: searchName,
      },
      { skip: pageType !== SettingsPageTypes.controller },
    );

  const { data: padletData, isFetching: isPadletDataFetching } =
    useGetPadletTypesQuery(
      {
        sortColumn: 'name',
        sortType,
        limit: DEFAULT_TABLE_PAGINATION_LIMIT,
        offset,
        name: searchName,
      },
      { skip: pageType !== SettingsPageTypes.padlet },
    );

  const deviceTypes = deviceData?.deviceTypes || [];
  const controllerTypes = controllerData?.controllerTypes || [];
  const padletTypes = padletData?.padletTypes || [];

  const types = new Map([
    [SettingsPageTypes.device, deviceTypes],
    [SettingsPageTypes.controller, controllerTypes],
    [SettingsPageTypes.padlet, padletTypes],
  ]);

  const paginationCount = new Map([
    [
      SettingsPageTypes.device,
      deviceData?.total
        ? Math.ceil(deviceData.total / DEFAULT_TABLE_PAGINATION_LIMIT)
        : 0,
    ],
    [
      SettingsPageTypes.controller,
      controllerData?.total
        ? Math.ceil(controllerData.total / DEFAULT_TABLE_PAGINATION_LIMIT)
        : 0,
    ],
    [
      SettingsPageTypes.padlet,
      padletData?.total
        ? Math.ceil(padletData.total / DEFAULT_TABLE_PAGINATION_LIMIT)
        : 0,
    ],
  ]);

  const isDataFetching = new Map([
    [SettingsPageTypes.device, isDeviceDataFetching],
    [SettingsPageTypes.controller, isControllerDataFetching],
    [SettingsPageTypes.padlet, isPadletDataFetching],
  ]);

  const count = paginationCount.get(pageType) || 0;

  const applyCustomPage = () => {
    setPage(Number(customPageValue));
  };

  const onPageChange = (_: ChangeEvent<unknown>, page: number) => {
    setPage(page);
  };

  const handleResetPagination = () => {
    setPage(DEFAULT_PAGE);
    setCustomPageValue(String(DEFAULT_PAGE));
  };

  const handleSwitchBackPage = () => {
    if (types.get(pageType)?.length === 1) {
      setPage((prevPage) => Math.max(DEFAULT_PAGE, prevPage - 1));
    }
  };

  const handleOpenUpdateModelDrawer = (type: DeviceType) => {
    setType(type);
    setDrawerType(updateDrawerTypes.get(pageType) as DrawerType);
  };

  const handleOpenDeleteModal = (type: DeviceType) => {
    setType(type);
    setIsDeleteModalOpen(true);
  };

  const isActionsVisible = (type: DeviceType): boolean => {
    if (
      (pageType === SettingsPageTypes.device ||
        pageType === SettingsPageTypes.padlet) &&
      type.pinned
    ) {
      return false;
    }

    return true;
  };

  useEffect(() => {
    setCustomPageValue(String(page));
  }, [page]);

  useEffect(() => {
    handleResetPagination();
  }, [searchName]);

  return {
    types,
    count,
    isDataFetching,
    page,
    sortType,

    handleSwitchBackPage,
    handleSortTypeChange,
    handleOpenDeleteModal,
    handleOpenUpdateModelDrawer,
    isActionsVisible,

    onPageChange,
    customPageValue,
    setCustomPageValue,
    applyCustomPage,

    type,
    isDeleteModalOpen,
    setIsDeleteModalOpen,
  };
};