From dd0388eeb82356ba71b33d601d5b7df18f3f6061 Mon Sep 17 00:00:00 2001 From: PavloDolia <123400767+PavloDolia@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:07:22 +0200 Subject: [PATCH] Fixed the bookmarked offers page (#2652) * fixed the bookmarked offers page * fixed tests --- .../BookmarksToolbar.styles.tsx | 1 + .../bookmarked-offers/BookmarksToolbar.tsx | 133 +++++++++--------- .../bookmarked-offers/BookmarkedOffers.tsx | 5 +- .../BookmarkedOffers.spec.jsx | 6 +- 4 files changed, 79 insertions(+), 66 deletions(-) diff --git a/src/containers/bookmarked-offers/BookmarksToolbar.styles.tsx b/src/containers/bookmarked-offers/BookmarksToolbar.styles.tsx index 45b931ac0..2745714d3 100644 --- a/src/containers/bookmarked-offers/BookmarksToolbar.styles.tsx +++ b/src/containers/bookmarked-offers/BookmarksToolbar.styles.tsx @@ -7,6 +7,7 @@ export const styles = { justifyContent: 'flex-start', alignItems: 'center', gap: '10px', + scrollMarginTop: '16px', [theme.breakpoints.up('md')]: { flexDirection: 'row', justifyContent: 'space-between', diff --git a/src/containers/bookmarked-offers/BookmarksToolbar.tsx b/src/containers/bookmarked-offers/BookmarksToolbar.tsx index 70964d395..ca6cf612c 100644 --- a/src/containers/bookmarked-offers/BookmarksToolbar.tsx +++ b/src/containers/bookmarked-offers/BookmarksToolbar.tsx @@ -1,4 +1,4 @@ -import { FormEvent, useState } from 'react' +import { FormEvent, forwardRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Box, IconButton } from '@mui/material' import ClearIcon from '@mui/icons-material/Clear' @@ -26,75 +26,80 @@ interface BookmarksToolbarProps { offersView: CardsView } -const BookmarksToolbar = ({ - filters, - updateFilters, - additionalParams, - offersView, - handleOffersView -}: BookmarksToolbarProps) => { - const [title, setTitle] = useState(filters.title) - const { t } = useTranslation() - const { isLaptopAndAbove } = useBreakpoints() +const BookmarksToolbar = forwardRef( + ( + { filters, updateFilters, additionalParams, offersView, handleOffersView }, + ref + ) => { + const [title, setTitle] = useState(filters.title) + const { t } = useTranslation() + const { isLaptopAndAbove } = useBreakpoints() - const handleInputSubmit = (e: FormEvent) => { - e.preventDefault() - updateFilters({ ...additionalParams, title }) - } + const handleInputChange = (event: React.ChangeEvent) => { + setTitle(event.target.value) + } - const handleSortBy = (value: string) => { - updateFilters({ ...additionalParams, sort: value }) - } + const handleInputSubmit = (e: FormEvent) => { + e.preventDefault() + updateFilters({ ...additionalParams, title }) + } - const sortOptions = sortTranslationKeys.map(({ title, value }) => ({ - title: t(title), - value - })) + const handleSortBy = (value: string) => { + updateFilters({ ...additionalParams, sort: value }) + } - const inputProps = { - endAdornment: filters.title ? ( - { - setTitle('') - updateFilters({ ...additionalParams, title: '' }) - }} - sx={{ p: 0 }} - > - - - ) : ( - - ) - } + const sortOptions = sortTranslationKeys.map(({ title, value }) => ({ + title: t(title), + value + })) + + const inputProps = { + endAdornment: filters.title ? ( + { + setTitle('') + updateFilters({ ...additionalParams, title: '' }) + }} + sx={{ p: 0 }} + > + + + ) : ( + + ) + } - return ( - - -
- + + + + + + + - + {isLaptopAndAbove && ( + + )} +
- - - {isLaptopAndAbove && ( - - )} - -
- ) -} + ) + } +) + +BookmarksToolbar.displayName = 'BookmarksToolbar' export default BookmarksToolbar diff --git a/src/pages/bookmarked-offers/BookmarkedOffers.tsx b/src/pages/bookmarked-offers/BookmarkedOffers.tsx index 2388380d0..821aed201 100644 --- a/src/pages/bookmarked-offers/BookmarkedOffers.tsx +++ b/src/pages/bookmarked-offers/BookmarkedOffers.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, useCallback, useEffect, useState } from 'react' +import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Divider } from '@mui/material' import Typography from '@mui/material/Typography' @@ -45,6 +45,7 @@ const BookmarkedOffers = () => { const { bookmarkedOffers } = useAppSelector((state) => state.editProfile) const { isMobile } = useBreakpoints() const dispatch = useAppDispatch() + const toolbarRef = useRef(null) const { t } = useTranslation() const { items, count: offersCount } = offers @@ -100,6 +101,7 @@ const BookmarkedOffers = () => { const handlePageChange = (_: ChangeEvent, page: number) => { filterQueryActions.updateFiltersInQuery({ page }) + toolbarRef.current?.scrollIntoView({ block: 'start', behavior: 'smooth' }) } useEffect(() => { @@ -116,6 +118,7 @@ const BookmarkedOffers = () => { filters={filters} handleOffersView={setCardsView} offersView={cardsView} + ref={toolbarRef} updateFilters={filterQueryActions.updateFiltersInQuery} /> diff --git a/tests/unit/pages/bookmarked-offers/BookmarkedOffers.spec.jsx b/tests/unit/pages/bookmarked-offers/BookmarkedOffers.spec.jsx index 62e5c278c..512e6f9d5 100644 --- a/tests/unit/pages/bookmarked-offers/BookmarkedOffers.spec.jsx +++ b/tests/unit/pages/bookmarked-offers/BookmarkedOffers.spec.jsx @@ -16,8 +16,11 @@ import * as sortValues from '~/containers/find-offer/offer-filter-block/OfferFil const mockNavigate = vi.fn() let mockSearchParams = new URLSearchParams() const mockSetSearchParams = vi.fn() +const mockScrollIntoView = vi.fn() const mockT = (str) => str +window.HTMLElement.prototype.scrollIntoView = mockScrollIntoView + vi.mock('react-router-dom', async () => { const actual = await vi.importActual('react-router-dom') return { @@ -77,7 +80,7 @@ describe('BookmarkedOffers page with offers', () => { expect(offer2Title).toBeInTheDocument() }) - it('should change the page number', async () => { + it('should change the page number and scroll to the top', async () => { const pageNumber = 2 const goToPageBtn = await screen.findByText(`${pageNumber}`, { selector: 'button' @@ -88,6 +91,7 @@ describe('BookmarkedOffers page with offers', () => { expect(mockSetSearchParams).toHaveBeenCalledWith( new URLSearchParams({ page: pageNumber }) ) + expect(mockScrollIntoView).toHaveBeenCalled() }) it('should add title to URL search params', async () => {