diff --git a/src/components/tab-filter-list/TabFilterList.tsx b/src/components/tab-filter-list/TabFilterList.tsx new file mode 100644 index 000000000..7031eab56 --- /dev/null +++ b/src/components/tab-filter-list/TabFilterList.tsx @@ -0,0 +1,37 @@ +import { Box, SxProps } from '@mui/material' +import Tab from '~/components/tab/Tab' + +import { useTranslation } from 'react-i18next' + +import { TabType } from '~/types' + +type TabFilterListProps = { + tabsData: Record> + activeTab: string + onClick: (tabName: string, tabValue: string) => void + sx?: SxProps +} + +const TabFilterList = ({ + tabsData, + activeTab, + onClick, + sx +}: TabFilterListProps) => { + const { t } = useTranslation() + + return ( + + {Object.entries(tabsData).map(([tabName, tab]) => ( + onClick(tabName, tab.value)} + > + {t(tab.label)} + + ))} + + ) +} +export default TabFilterList diff --git a/src/pages/my-cooperations/MyCooperations.tsx b/src/pages/my-cooperations/MyCooperations.tsx index fd6cd31d6..5d1a7f8d6 100644 --- a/src/pages/my-cooperations/MyCooperations.tsx +++ b/src/pages/my-cooperations/MyCooperations.tsx @@ -1,6 +1,6 @@ -import { useCallback, useLayoutEffect, useState } from 'react' +import { useCallback, useEffect, useLayoutEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { Link } from 'react-router-dom' +import { Link, useSearchParams } from 'react-router-dom' import Box from '@mui/material/Box' import Typography from '@mui/material/Typography' @@ -11,7 +11,6 @@ import useAxios from '~/hooks/use-axios' import useSort from '~/hooks/table/use-sort' import useBreakpoints from '~/hooks/use-breakpoints' import useFilter from '~/hooks/table/use-filter' -import Tab from '~/components/tab/Tab' import Loader from '~/components/loader/Loader' import AppButton from '~/components/app-button/AppButton' import AppPagination from '~/components/app-pagination/AppPagination' @@ -30,8 +29,11 @@ import { tabsInfo } from '~/pages/my-cooperations/MyCooperations.constants' import { itemsLoadLimit } from '~/constants' -import { CardsViewEnum, TabType, UserRoleEnum } from '~/types' +import { CardsViewEnum, UserRoleEnum } from '~/types' import { styles } from '~/pages/my-cooperations/MyCooperations.styles' +import TabFilterList from '~/components/tab-filter-list/TabFilterList' + +type TabKey = keyof typeof tabsInfo const MyCooperations = () => { const [itemsView, setItemsView] = useState( @@ -40,8 +42,13 @@ const MyCooperations = () => { const { t } = useTranslation() const dispatch = useAppDispatch() const breakpoints = useBreakpoints() + const [searchParams, setSearchParams] = useSearchParams() + const activeTab = searchParams.get('tab') const filterOptions = useFilter({ - initialFilters + initialFilters: { + ...initialFilters, + status: activeTab ? tabsInfo[activeTab as TabKey].value : '' + } }) const sortOptions = useSort({ initialSort @@ -51,6 +58,12 @@ const MyCooperations = () => { const { filters, clearFilters, setFilterByKey } = filterOptions const { userRole } = useAppSelector((state) => state.appMain) + useEffect(() => { + if (!activeTab) { + setSearchParams({ tab: Object.keys(tabsInfo)[0] }) + } + }, [activeTab, setSearchParams]) + const itemsPerPage = getScreenBasedLimit(breakpoints, itemsLoadLimit) const showTable = !breakpoints.isMobile && itemsView === CardsViewEnum.Inline @@ -75,22 +88,13 @@ const MyCooperations = () => { defaultResponse }) - const handleTabClick = (tab: TabType) => { + const handleTabClick = (tabName: string, tabValue: string) => { clearFilters() resetSort() - setFilterByKey('status')(tab.value) + setFilterByKey('status')(tabValue) + setSearchParams({ tab: tabName }) } - const tabs = Object.values(tabsInfo).map((tab) => ( - handleTabClick(tab)} - > - {t(tab.label)} - - )) - const sortFields = sortTranslationKeys.map(({ title, value }) => ({ title: t(title), value @@ -115,7 +119,12 @@ const MyCooperations = () => { {t(`button.view.${userRole}`)} - {tabs} + { const [itemsView, setItemsView] = useState( CardsViewEnum.Inline @@ -42,8 +45,13 @@ const MyOffers = () => { const { t } = useTranslation() const dispatch = useAppDispatch() const breakpoints = useBreakpoints() + const [searchParams, setSearchParams] = useSearchParams() + const activeTab = searchParams.get('tab') const filterOptions = useFilter({ - initialFilters + initialFilters: { + ...initialFilters, + status: activeTab ? tabsInfo[activeTab as TabName].value : '' + } }) const sortOptions = useSort({ initialSort @@ -56,6 +64,12 @@ const MyOffers = () => { const handleOpenDrawer = () => openDrawer() + useEffect(() => { + if (!activeTab) { + setSearchParams({ tab: Object.keys(tabsInfo)[0] }) + } + }, [activeTab, setSearchParams]) + const itemsPerPage = getScreenBasedLimit(breakpoints, itemsLoadLimit) const showTable = !breakpoints.isMobile && itemsView === CardsViewEnum.Inline @@ -79,22 +93,13 @@ const MyOffers = () => { defaultResponse }) - const handleTabClick = (tab: TabType) => { + const handleTabClick = (tabName: string, tabValue: string) => { + setSearchParams({ tab: tabName }) clearFilters() resetSort() - setFilterByKey('status')(tab.value) + setFilterByKey('status')(tabValue) } - const tabs = Object.values(tabsInfo).map((tab) => ( - handleTabClick(tab)} - > - {t(tab.label)} - - )) - const sortFields = sortTranslationKeys.map(({ title, value }) => ({ title: t(title), value @@ -117,7 +122,12 @@ const MyOffers = () => { - {tabs} + { + beforeEach(() => { + render( + + ) + }) + + it('renders TabFilterList correctly', () => { + expect(screen.getByText('Tab 1')).toBeInTheDocument() + expect(screen.getByText('Tab 2')).toBeInTheDocument() + }) + + it('calls handleClick when a tab is clicked', () => { + fireEvent.click(screen.getByText('Tab 2')) + expect(handleClickMock).toHaveBeenCalled() + }) +})