From a83f2c7e7178a19e466b6a2701b7a67ec0381293 Mon Sep 17 00:00:00 2001 From: Alexis Graff Date: Sun, 20 Oct 2024 19:55:13 -0300 Subject: [PATCH] refactor/ag/create-hook-for-pagination-and-filter (#98) --- src/features/items/organisms/List.tsx | 73 +++-------------- src/features/shared/actions/fetchUsers.ts | 0 .../shared/hooks/useFilterAndPagination.tsx | 82 +++++++++++++++++++ src/features/users/organisms/UsersList.tsx | 71 +++------------- 4 files changed, 105 insertions(+), 121 deletions(-) create mode 100644 src/features/shared/actions/fetchUsers.ts create mode 100644 src/features/shared/hooks/useFilterAndPagination.tsx diff --git a/src/features/items/organisms/List.tsx b/src/features/items/organisms/List.tsx index 379437e4..8ec8a672 100644 --- a/src/features/items/organisms/List.tsx +++ b/src/features/items/organisms/List.tsx @@ -1,6 +1,5 @@ 'use client'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React from 'react'; import { useTranslations } from 'next-intl'; import { deleteItem } from '@/features/items/actions/ItemAction'; @@ -14,15 +13,12 @@ import { PaginationComponent } from '@/features/shared/atoms/pagination/Paginati import { SelectColorType } from '@/features/shared/atoms/select/SelectForm'; import { SizeType, SwitchComponent } from '@/features/shared/atoms/swich/switch'; import { Title } from '@/features/shared/atoms/title/Title'; -import { useFilter } from '@/features/shared/hooks/useFilter'; -import { usePagination } from '@/features/shared/hooks/usePagination'; +import { useFilterAndPagination } from '@/features/shared/hooks/useFilterAndPagination'; import { PaginationAPI } from '@/features/shared/interfaces/PaginationAPI'; import { FiltersApplied } from '@/features/shared/molecules/filtersApplied/FiltersApplied'; import { SortComponent } from '@/features/shared/molecules/sort/Sort'; import { FilterAndSearch } from '@/features/shared/organisms/filterAndSearch/FilterAndSearch'; -import { OptionKey } from '@/features/users/interfaces/OptionKey'; - import styleCard from './card.module.css'; import style from './list.module.css'; @@ -31,65 +27,20 @@ type Props = { pagination: PaginationAPI; }; export const List = ({ items, pagination }: Props) => { - const [keySelected, setKeySelected] = useState({ ...selectOptionsData[0] }); - const searchParams = useSearchParams(); - const params = useMemo(() => { - const newParams = new URLSearchParams(); - - const entriesArray = Array.from(searchParams.entries()); - for (const [key, value] of entriesArray) { - newParams.append(key, value); - } - - return newParams; - }, [searchParams]); - const pathname = usePathname(); - const { replace } = useRouter(); - const { handlePage, currentPage } = usePagination(pagination, params); + const t = useTranslations('Items'); const { - handleSetFilterValues, - filterValues, - filtersApplied, + handlePage, + currentPage, handleRemoveFilter, handleSetFiltersApplied, handleRemoveFilterAll, - } = useFilter(params); - const t = useTranslations('Items'); - - const [openDropdownId, setOpenDropdownId] = useState(null); - - const handleDropdown = (id: string) => { - setOpenDropdownId(openDropdownId === id ? null : id); - }; - - const handleReplaceURL = () => { - replace(`${pathname}?${params.toString()}`); - }; - - const handleSearchType = useCallback(() => { - const data = selectOptionsData.find(({ value }) => value === filterValues.key); - if (data) { - setKeySelected(data); - } - }, [filterValues.key]); - - useEffect(() => { - handleSetFilterValues({ - key: selectOptionsData[0].value, - }); - }, []); - - useEffect(() => { - handlePage(1); - }, [filterValues.term]); - - useEffect(() => { - handleSearchType(); - }, [handleSearchType]); - - useEffect(() => { - handleReplaceURL(); - }, [currentPage]); + filtersApplied, + handleDropdown, + openDropdownId, + keySelected, + handleSetFilterValues, + handleReplaceURL, + } = useFilterAndPagination(selectOptionsData, pagination); return (
diff --git a/src/features/shared/actions/fetchUsers.ts b/src/features/shared/actions/fetchUsers.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/features/shared/hooks/useFilterAndPagination.tsx b/src/features/shared/hooks/useFilterAndPagination.tsx new file mode 100644 index 00000000..f7d1675b --- /dev/null +++ b/src/features/shared/hooks/useFilterAndPagination.tsx @@ -0,0 +1,82 @@ +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; + +import { useFilter } from '@/features/shared/hooks/useFilter'; +import { usePagination } from '@/features/shared/hooks/usePagination'; +import { OptionKey } from '@/features/users/interfaces/OptionKey'; + +export const useFilterAndPagination = (selectOptionsData: OptionKey[], pagination: any) => { + const [keySelected, setKeySelected] = useState({ ...selectOptionsData[0] }); + const searchParams = useSearchParams(); + const params = useMemo(() => { + const newParams = new URLSearchParams(); + const entriesArray = Array.from(searchParams.entries()); + for (const [key, value] of entriesArray) { + newParams.append(key, value); + } + return newParams; + }, [searchParams]); + + const handleReplaceURL = () => { + replace(`${pathname}?${params.toString()}`); + }; + + const pathname = usePathname(); + const { replace } = useRouter(); + const { handlePage, currentPage } = usePagination(pagination, params); + const { + filterValues, + filtersApplied, + handleRemoveFilter, + handleSetFiltersApplied, + handleRemoveFilterAll, + handleSetFilterValues, + } = useFilter(params); + + const [openDropdownId, setOpenDropdownId] = useState(null); + + const handleDropdown = (id: string) => { + setOpenDropdownId(openDropdownId === id ? null : id); + }; + + const handleSearchType = useCallback(() => { + const data = selectOptionsData.find(({ value }) => value === filterValues.key); + if (data) { + setKeySelected(data); + } + }, [filterValues.key, selectOptionsData]); + + useEffect(() => { + handleSetFilterValues({ + key: selectOptionsData[0].value, + }); + }, [selectOptionsData, handleSetFilterValues]); + + useEffect(() => { + handlePage(1); + }, [filterValues.term, handlePage]); + + useEffect(() => { + handleSearchType(); + }, [handleSearchType]); + + useEffect(() => { + handleReplaceURL(); + }, [currentPage, handleReplaceURL]); + + return { + keySelected, + setKeySelected, + filterValues, + filtersApplied, + handleRemoveFilter, + handleSetFiltersApplied, + handleRemoveFilterAll, + openDropdownId, + handleDropdown, + currentPage, + handlePage, + handleSetFilterValues, + handleReplaceURL, + }; +}; diff --git a/src/features/users/organisms/UsersList.tsx b/src/features/users/organisms/UsersList.tsx index 0446fb94..f359d513 100644 --- a/src/features/users/organisms/UsersList.tsx +++ b/src/features/users/organisms/UsersList.tsx @@ -1,7 +1,5 @@ 'use client'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; - -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React from 'react'; import { useTranslations } from 'next-intl'; @@ -15,14 +13,12 @@ import { SelectColorType } from '@/features/shared/atoms/select/SelectForm'; import { SizeType } from '@/features/shared/atoms/swich/switch'; import { Title } from '@/features/shared/atoms/title/Title'; -import { useFilter } from '@/features/shared/hooks/useFilter'; +import { useFilterAndPagination } from '@/features/shared/hooks/useFilterAndPagination'; import { UserHasRole } from '@/features/shared/interfaces/UserHasRole'; import { FiltersApplied } from '@/features/shared/molecules/filtersApplied/FiltersApplied'; import { FilterAndSearch } from '@/features/shared/organisms/filterAndSearch/FilterAndSearch'; -import { usePagination } from '@/features/users/atoms/usePagination/usePagination'; import { selectOptionsData } from '@/features/users/constants/selectOptionsData'; -import { OptionKey } from '@/features/users/interfaces/OptionKey'; import styles from './users-list.module.css'; @@ -33,64 +29,19 @@ interface Props { export const UserList = (props: Props) => { const t = useTranslations('UserList'); - const [keySelected, setKeySelected] = useState({ ...selectOptionsData[0] }); - const pathname = usePathname(); - const { replace } = useRouter(); - const searchParams = useSearchParams(); - const params = useMemo(() => { - const newParams = new URLSearchParams(); - - const entriesArray = Array.from(searchParams.entries()); - for (const [key, value] of entriesArray) { - newParams.append(key, value); - } - - return newParams; - }, [searchParams]); - const { handlePage, currentPage } = usePagination(props.pagination, params); const { - handleSetFilterValues, - filterValues, - filtersApplied, + handlePage, + currentPage, handleRemoveFilter, handleSetFiltersApplied, handleRemoveFilterAll, - } = useFilter(params); - - const [openDropdownId, setOpenDropdownId] = useState(null); - - const handleReplaceURL = () => { - replace(`${pathname}?${params.toString()}`); - }; - - const handleSearchType = useCallback(() => { - const data = selectOptionsData.find(({ value }) => value === filterValues.key); - if (data) { - setKeySelected(data); - } - }, [filterValues.key]); - - const handleDropdown = (id: string) => { - setOpenDropdownId(openDropdownId === id ? null : id); - }; - - useEffect(() => { - handleSetFilterValues({ - key: selectOptionsData[0].value, - }); - }, []); - - useEffect(() => { - handlePage(1); - }, [filterValues.term]); - - useEffect(() => { - handleSearchType(); - }, [handleSearchType]); - - useEffect(() => { - handleReplaceURL(); - }, [currentPage]); + filtersApplied, + handleDropdown, + openDropdownId, + keySelected, + handleSetFilterValues, + handleReplaceURL, + } = useFilterAndPagination(selectOptionsData, props.pagination); return (