From 3b87c1aa2ad23ff38372ed48ead9abe7810a95c2 Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Mon, 27 Jan 2025 19:28:45 +0100 Subject: [PATCH 1/7] Pagination - added --- .../src/components/Pagination/Pagination.tsx | 165 ++++++++++++++++++ .../src/components/Pagination/index.ts | 1 + .../components/Pagination/usePagination.tsx | 32 ++++ .../components/AllMachines/AllMachines.tsx | 15 ++ 4 files changed, 213 insertions(+) create mode 100644 packages/web-app/src/components/Pagination/Pagination.tsx create mode 100644 packages/web-app/src/components/Pagination/index.ts create mode 100644 packages/web-app/src/components/Pagination/usePagination.tsx diff --git a/packages/web-app/src/components/Pagination/Pagination.tsx b/packages/web-app/src/components/Pagination/Pagination.tsx new file mode 100644 index 000000000..fdd0eeee4 --- /dev/null +++ b/packages/web-app/src/components/Pagination/Pagination.tsx @@ -0,0 +1,165 @@ +import { Button, Text } from '@saladtechnologies/garden-components' +import type CSS from 'csstype' +import type { FunctionComponent } from 'react' +import type { WithStyles } from 'react-jss' +import withStyles from 'react-jss' +import { DefaultTheme, type SaladTheme } from '../../SaladTheme' + +const styles: (theme: SaladTheme) => Record = (theme: SaladTheme) => ({ + paginationWrapper: { + width: '100%', + color: theme.lightGreen, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + gap: '16px', + padding: '16px', + }, + navigationButtonWrapper: { + width: '100px', + }, + centralPagesWrapper: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + gap: '6px', + width: '300px', + }, + currentPageWrapper: { + backgroundColor: theme.lightGreen, + width: '32px', + height: '32px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + }, + currentPageText: { + color: theme.darkBlue, + }, + dotsWrapper: { + width: '32px', + height: '32px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + }, +}) + +interface Props extends WithStyles { + itemsTotalAmount: number + itemsPerPageAmount: number + currentPageNumber?: number + onPageChange: (pageNumber: number) => void +} + +const _Pagination: FunctionComponent = ({ + classes, + itemsTotalAmount, + itemsPerPageAmount = 10, + currentPageNumber = 1, + onPageChange, +}) => { + const totalPagesAmount = Math.ceil(itemsTotalAmount / itemsPerPageAmount) + const withPreviousPage = currentPageNumber !== 1 + const withNextPage = totalPagesAmount - currentPageNumber > 0 + const firstPageNumber = 1 + const lastPageNumber = totalPagesAmount + const nextPageNumber = currentPageNumber + 1 + const previousPageNumber = currentPageNumber - 1 + const withNextDots = nextPageNumber !== lastPageNumber + const withPreviousDots = previousPageNumber !== firstPageNumber + const isNextPageLast = nextPageNumber === totalPagesAmount + const isPreviousPageFirst = previousPageNumber === firstPageNumber + + return ( +
+
+ {withPreviousPage && ( +
+
+ {withPreviousPage && !isPreviousPageFirst && ( +
+
+ {withNextPage && ( +
+
+ ) +} + +export const Pagination = withStyles(styles)(_Pagination) diff --git a/packages/web-app/src/components/Pagination/index.ts b/packages/web-app/src/components/Pagination/index.ts new file mode 100644 index 000000000..fe3b56b97 --- /dev/null +++ b/packages/web-app/src/components/Pagination/index.ts @@ -0,0 +1 @@ +export * from './Pagination' diff --git a/packages/web-app/src/components/Pagination/usePagination.tsx b/packages/web-app/src/components/Pagination/usePagination.tsx new file mode 100644 index 000000000..c1f35da0a --- /dev/null +++ b/packages/web-app/src/components/Pagination/usePagination.tsx @@ -0,0 +1,32 @@ +import { useState } from 'react' + +interface UsePaginationParams { + itemsPerPageAmount?: number + initialCurrentPageNumber?: number +} + +const defaultItemsPerPageAmount = 10 +const defaultInitialCurrentPageNumber = 10 + +export const usePagination = (params?: UsePaginationParams) => { + const { itemsPerPageAmount = defaultItemsPerPageAmount, initialCurrentPageNumber = defaultInitialCurrentPageNumber } = + params + ? params + : { + itemsPerPageAmount: defaultItemsPerPageAmount, + initialCurrentPageNumber: defaultInitialCurrentPageNumber, + } + + const [currentPageNumber, setCurrentPageNumber] = useState(initialCurrentPageNumber) + + const minItemNumberOnPage = itemsPerPageAmount * currentPageNumber + const maxItemNumberOnPage = minItemNumberOnPage + itemsPerPageAmount + + return { + setCurrentPageNumber, + currentPageNumber, + minItemNumberOnPage, + maxItemNumberOnPage, + itemsPerPageAmount, + } +} diff --git a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx index ce2f72226..cfce84254 100644 --- a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx +++ b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx @@ -7,6 +7,8 @@ import { DateTime } from 'luxon' import { useState } from 'react' import type { WithStyles } from 'react-jss' import withStyles from 'react-jss' +import { Pagination } from '../../../../components/Pagination' +import { usePagination } from '../../../../components/Pagination/usePagination' import { Table } from '../../../../components/Table' import type { TableRow } from '../../../../components/Table/types' import { DefaultTheme, type SaladTheme } from '../../../../SaladTheme' @@ -105,6 +107,9 @@ const _AllMachines = ({ classes }: Props) => { window.location.href = 'https://support.salad.com/article/414-how-to-find-your-salad-machine-id' } + const { minItemNumberOnPage, maxItemNumberOnPage, currentPageNumber, itemsPerPageAmount, setCurrentPageNumber } = + usePagination() + const getTitles = () => { return [
@@ -138,6 +143,10 @@ const _AllMachines = ({ classes }: Props) => { const getRows = (): Array => { return generatedMockedMachines + .filter((_machine, index) => { + const itemNumber = index + 1 + return itemNumber >= minItemNumberOnPage && itemNumber < maxItemNumberOnPage + }) .map((machine) => { return { checkbox: ( @@ -183,6 +192,12 @@ const _AllMachines = ({ classes }: Props) => { All Machines
+ setCurrentPageNumber(pageNumber)} + /> ) From 5b0391ac8a34ac63ac6f7a6a47584817827ac888 Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Tue, 28 Jan 2025 16:09:07 +0100 Subject: [PATCH 2/7] _Pagination: improved ot handle large page numbers --- .../src/components/Pagination/Pagination.tsx | 130 +++++++++--------- .../components/AllMachines/mocks.ts | 2 +- 2 files changed, 69 insertions(+), 63 deletions(-) diff --git a/packages/web-app/src/components/Pagination/Pagination.tsx b/packages/web-app/src/components/Pagination/Pagination.tsx index fdd0eeee4..a1e63ec55 100644 --- a/packages/web-app/src/components/Pagination/Pagination.tsx +++ b/packages/web-app/src/components/Pagination/Pagination.tsx @@ -1,4 +1,5 @@ import { Button, Text } from '@saladtechnologies/garden-components' +import classNames from 'classnames' import type CSS from 'csstype' import type { FunctionComponent } from 'react' import type { WithStyles } from 'react-jss' @@ -19,33 +20,52 @@ const styles: (theme: SaladTheme) => Record = (theme: Sa navigationButtonWrapper: { width: '100px', }, + pagesNavigationWrapper: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + gap: '6px', + width: '250px', + }, centralPagesWrapper: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'row', gap: '6px', - width: '300px', }, - currentPageWrapper: { - backgroundColor: theme.lightGreen, - width: '32px', - height: '32px', + edgePagesWrapper: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'row', + gap: '6px', + width: '60px', }, currentPageText: { color: theme.darkBlue, }, - dotsWrapper: { - width: '32px', + button: { + minWidth: '32px', + padding: '0px 6px', height: '32px', display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'row', + backgroundColor: 'transparent', + color: 'inherit', + border: `1px solid ${theme.lightGreen}`, + font: 'inherit', + cursor: 'pointer', + outline: 'inherit', + fontFamily: theme.fontMallory, + }, + currentPageButton: { + backgroundColor: theme.lightGreen, + color: theme.darkBlue, + fontWeight: 500, }, }) @@ -89,62 +109,48 @@ const _Pagination: FunctionComponent = ({ /> )} -
- {withPreviousPage && !isPreviousPageFirst && ( - + )} + {withPreviousDots && withPreviousPage && ( +
+ ... +
+ )} +
+
+ {withPreviousPage && ( + + )} + + {withNextPage && ( + + )} +
+
+ {withNextDots && withNextPage && ( +
+ ... +
+ )} + {!isNextPageLast && withNextPage && ( + + )}
- {withNextPage && withNextPage && ( - )} - {withPreviousDots && withPreviousPage && ( + {withPreviousDots && isPreviousPageEnabled && (
...
)}
- {withPreviousPage && ( + {isPreviousPageEnabled && ( @@ -133,36 +140,35 @@ const _Pagination: FunctionComponent = ({ {currentPageNumber} - {withNextPage && ( + {isNextPageEnabled && ( )}
- {withNextDots && withNextPage && ( + {withNextDots && isNextPageEnabled && (
...
)} - {!isNextPageLast && withNextPage && ( + {!isNextPageLast && isNextPageEnabled && ( )}
-
- {withNextPage && ( -
) From 9c99ee32cd5e52531d496293113a4f512ee135b6 Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Tue, 28 Jan 2025 17:55:29 +0100 Subject: [PATCH 4/7] Pagination: wrong items on page issue - fixed --- .../src/components/Pagination/usePagination.tsx | 10 +++++----- .../earn-views/components/AllMachines/AllMachines.tsx | 4 ++-- .../modules/earn-views/components/AllMachines/mocks.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/web-app/src/components/Pagination/usePagination.tsx b/packages/web-app/src/components/Pagination/usePagination.tsx index c1f35da0a..e09479c06 100644 --- a/packages/web-app/src/components/Pagination/usePagination.tsx +++ b/packages/web-app/src/components/Pagination/usePagination.tsx @@ -6,7 +6,7 @@ interface UsePaginationParams { } const defaultItemsPerPageAmount = 10 -const defaultInitialCurrentPageNumber = 10 +const defaultInitialCurrentPageNumber = 1 export const usePagination = (params?: UsePaginationParams) => { const { itemsPerPageAmount = defaultItemsPerPageAmount, initialCurrentPageNumber = defaultInitialCurrentPageNumber } = @@ -19,14 +19,14 @@ export const usePagination = (params?: UsePaginationParams) => { const [currentPageNumber, setCurrentPageNumber] = useState(initialCurrentPageNumber) - const minItemNumberOnPage = itemsPerPageAmount * currentPageNumber - const maxItemNumberOnPage = minItemNumberOnPage + itemsPerPageAmount + const higherItemNumberOnPage = itemsPerPageAmount * currentPageNumber + const lowerItemNumberOnPage = higherItemNumberOnPage - itemsPerPageAmount + 1 return { setCurrentPageNumber, + lowerItemNumberOnPage, + higherItemNumberOnPage, currentPageNumber, - minItemNumberOnPage, - maxItemNumberOnPage, itemsPerPageAmount, } } diff --git a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx index cfce84254..c24c5f0f5 100644 --- a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx +++ b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx @@ -107,7 +107,7 @@ const _AllMachines = ({ classes }: Props) => { window.location.href = 'https://support.salad.com/article/414-how-to-find-your-salad-machine-id' } - const { minItemNumberOnPage, maxItemNumberOnPage, currentPageNumber, itemsPerPageAmount, setCurrentPageNumber } = + const { lowerItemNumberOnPage, higherItemNumberOnPage, currentPageNumber, itemsPerPageAmount, setCurrentPageNumber } = usePagination() const getTitles = () => { @@ -145,7 +145,7 @@ const _AllMachines = ({ classes }: Props) => { return generatedMockedMachines .filter((_machine, index) => { const itemNumber = index + 1 - return itemNumber >= minItemNumberOnPage && itemNumber < maxItemNumberOnPage + return itemNumber >= lowerItemNumberOnPage && itemNumber <= higherItemNumberOnPage }) .map((machine) => { return { diff --git a/packages/web-app/src/modules/earn-views/components/AllMachines/mocks.ts b/packages/web-app/src/modules/earn-views/components/AllMachines/mocks.ts index a22bb87a0..b098e3d05 100644 --- a/packages/web-app/src/modules/earn-views/components/AllMachines/mocks.ts +++ b/packages/web-app/src/modules/earn-views/components/AllMachines/mocks.ts @@ -21,7 +21,7 @@ export const getRandomId = (): string => { } const generateMockedMachines = () => { - return Array(5000) + return Array(100) .fill(null) .map(() => ({ id: getRandomId().toLocaleLowerCase(), From 2943c401b5475400052bb63cd3bac0c5a77654d9 Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Wed, 29 Jan 2025 16:02:20 +0100 Subject: [PATCH 5/7] usePagination: naming refactor --- .../src/components/Pagination/usePagination.tsx | 8 ++++---- .../earn-views/components/AllMachines/AllMachines.tsx | 11 ++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/web-app/src/components/Pagination/usePagination.tsx b/packages/web-app/src/components/Pagination/usePagination.tsx index e09479c06..5aee4c463 100644 --- a/packages/web-app/src/components/Pagination/usePagination.tsx +++ b/packages/web-app/src/components/Pagination/usePagination.tsx @@ -19,13 +19,13 @@ export const usePagination = (params?: UsePaginationParams) => { const [currentPageNumber, setCurrentPageNumber] = useState(initialCurrentPageNumber) - const higherItemNumberOnPage = itemsPerPageAmount * currentPageNumber - const lowerItemNumberOnPage = higherItemNumberOnPage - itemsPerPageAmount + 1 + const highestItemNumberOnPage = itemsPerPageAmount * currentPageNumber + const lowestItemNumberOnPage = highestItemNumberOnPage - itemsPerPageAmount + 1 return { setCurrentPageNumber, - lowerItemNumberOnPage, - higherItemNumberOnPage, + lowestItemNumberOnPage, + highestItemNumberOnPage, currentPageNumber, itemsPerPageAmount, } diff --git a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx index c24c5f0f5..9a742524b 100644 --- a/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx +++ b/packages/web-app/src/modules/earn-views/components/AllMachines/AllMachines.tsx @@ -107,8 +107,13 @@ const _AllMachines = ({ classes }: Props) => { window.location.href = 'https://support.salad.com/article/414-how-to-find-your-salad-machine-id' } - const { lowerItemNumberOnPage, higherItemNumberOnPage, currentPageNumber, itemsPerPageAmount, setCurrentPageNumber } = - usePagination() + const { + lowestItemNumberOnPage, + highestItemNumberOnPage, + currentPageNumber, + itemsPerPageAmount, + setCurrentPageNumber, + } = usePagination() const getTitles = () => { return [ @@ -145,7 +150,7 @@ const _AllMachines = ({ classes }: Props) => { return generatedMockedMachines .filter((_machine, index) => { const itemNumber = index + 1 - return itemNumber >= lowerItemNumberOnPage && itemNumber <= higherItemNumberOnPage + return itemNumber >= lowestItemNumberOnPage && itemNumber <= highestItemNumberOnPage }) .map((machine) => { return { From 469f67f7ee586ce78eea5025ba2d5a55fd8acfd2 Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Thu, 30 Jan 2025 16:15:14 +0100 Subject: [PATCH 6/7] _Pagination: refactor --- .../src/components/Pagination/Pagination.tsx | 2 +- .../src/components/Pagination/usePagination.tsx | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/web-app/src/components/Pagination/Pagination.tsx b/packages/web-app/src/components/Pagination/Pagination.tsx index 24492d553..1e926d1cf 100644 --- a/packages/web-app/src/components/Pagination/Pagination.tsx +++ b/packages/web-app/src/components/Pagination/Pagination.tsx @@ -93,7 +93,7 @@ const _Pagination: FunctionComponent = ({ }) => { const totalPagesAmount = Math.ceil(itemsTotalAmount / itemsPerPageAmount) const isPreviousPageEnabled = currentPageNumber !== 1 - const isNextPageEnabled = totalPagesAmount - currentPageNumber > 0 + const isNextPageEnabled = currentPageNumber < totalPagesAmount const firstPageNumber = 1 const lastPageNumber = totalPagesAmount const nextPageNumber = currentPageNumber + 1 diff --git a/packages/web-app/src/components/Pagination/usePagination.tsx b/packages/web-app/src/components/Pagination/usePagination.tsx index 5aee4c463..13827812b 100644 --- a/packages/web-app/src/components/Pagination/usePagination.tsx +++ b/packages/web-app/src/components/Pagination/usePagination.tsx @@ -8,15 +8,15 @@ interface UsePaginationParams { const defaultItemsPerPageAmount = 10 const defaultInitialCurrentPageNumber = 1 -export const usePagination = (params?: UsePaginationParams) => { - const { itemsPerPageAmount = defaultItemsPerPageAmount, initialCurrentPageNumber = defaultInitialCurrentPageNumber } = - params - ? params - : { - itemsPerPageAmount: defaultItemsPerPageAmount, - initialCurrentPageNumber: defaultInitialCurrentPageNumber, - } +const defaultParams = { + itemsPerPageAmount: defaultItemsPerPageAmount, + initialCurrentPageNumber: defaultInitialCurrentPageNumber, +} +export const usePagination = ({ + itemsPerPageAmount = defaultParams.itemsPerPageAmount, + initialCurrentPageNumber = defaultParams.initialCurrentPageNumber, +}: UsePaginationParams = defaultParams) => { const [currentPageNumber, setCurrentPageNumber] = useState(initialCurrentPageNumber) const highestItemNumberOnPage = itemsPerPageAmount * currentPageNumber From d1ccfaa85e406bc4a54ed1e277cc9d732b6f2ddc Mon Sep 17 00:00:00 2001 From: Viktor Mozharovskyi Date: Thu, 30 Jan 2025 17:33:47 +0100 Subject: [PATCH 7/7] _Pagination: refactor --- packages/web-app/src/components/Pagination/Pagination.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-app/src/components/Pagination/Pagination.tsx b/packages/web-app/src/components/Pagination/Pagination.tsx index 1e926d1cf..9489ef59d 100644 --- a/packages/web-app/src/components/Pagination/Pagination.tsx +++ b/packages/web-app/src/components/Pagination/Pagination.tsx @@ -92,7 +92,7 @@ const _Pagination: FunctionComponent = ({ onPageChange, }) => { const totalPagesAmount = Math.ceil(itemsTotalAmount / itemsPerPageAmount) - const isPreviousPageEnabled = currentPageNumber !== 1 + const isPreviousPageEnabled = currentPageNumber > 1 const isNextPageEnabled = currentPageNumber < totalPagesAmount const firstPageNumber = 1 const lastPageNumber = totalPagesAmount