From a91917fde5661a1a1c116a2892c8167435cce9e9 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sat, 27 Dec 2025 18:00:09 +0000 Subject: [PATCH] refactor: split pagination components --- .../src/components/ui/organisms/index.ts | 2 +- .../ui/organisms/navigation/Navigation.tsx | 4 +- .../ui/organisms/navigation/Pagination.tsx | 406 ------------------ .../navigation/pagination/Pagination.test.tsx | 122 ++++++ .../pagination/PaginationContent.tsx | 49 +++ .../pagination/PaginationEllipsis.tsx | 27 ++ .../navigation/pagination/PaginationLink.tsx | 35 ++ .../navigation/pagination/PaginationNext.tsx | 18 + .../pagination/PaginationPrevious.tsx | 18 + .../navigation/pagination/PaginationRoot.tsx | 63 +++ .../pagination/SimplePagination.tsx | 89 ++++ .../navigation/pagination/TablePagination.tsx | 128 ++++++ .../organisms/navigation/pagination/index.ts | 13 + .../navigation/pagination/paginationUtils.tsx | 24 ++ .../{ => utils}/navigationConfig.ts | 0 .../{ => utils}/navigationHelpers.ts | 0 16 files changed, 589 insertions(+), 409 deletions(-) delete mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/Pagination.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/Pagination.test.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationContent.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationEllipsis.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationLink.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationNext.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationPrevious.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationRoot.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/SimplePagination.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/TablePagination.tsx create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/index.ts create mode 100644 frontends/nextjs/src/components/ui/organisms/navigation/pagination/paginationUtils.tsx rename frontends/nextjs/src/components/ui/organisms/navigation/{ => utils}/navigationConfig.ts (100%) rename frontends/nextjs/src/components/ui/organisms/navigation/{ => utils}/navigationHelpers.ts (100%) diff --git a/frontends/nextjs/src/components/ui/organisms/index.ts b/frontends/nextjs/src/components/ui/organisms/index.ts index 29ac2094d..4e1306216 100644 --- a/frontends/nextjs/src/components/ui/organisms/index.ts +++ b/frontends/nextjs/src/components/ui/organisms/index.ts @@ -74,7 +74,7 @@ export { PaginationEllipsis, PaginationPrevious, PaginationNext, -} from './navigation/Pagination' +} from './navigation/pagination' // Navigation export { diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/Navigation.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/Navigation.tsx index 26db2774f..c6313dbd7 100644 --- a/frontends/nextjs/src/components/ui/organisms/navigation/Navigation.tsx +++ b/frontends/nextjs/src/components/ui/organisms/navigation/Navigation.tsx @@ -12,8 +12,8 @@ import { NavigationLink, } from './NavigationMenuItems' import { NavigationBrand, NavigationSeparator, NavigationSpacer } from './NavigationStyling' -import { NavigationItemType } from './navigationConfig' -import { useNavigationDropdown } from './navigationHelpers' +import { NavigationItemType } from './utils/navigationConfig' +import { useNavigationDropdown } from './utils/navigationHelpers' interface NavigationProps { children: ReactNode diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/Pagination.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/Pagination.tsx deleted file mode 100644 index 4160805af..000000000 --- a/frontends/nextjs/src/components/ui/organisms/navigation/Pagination.tsx +++ /dev/null @@ -1,406 +0,0 @@ -// TODO: Split this file (405 LOC) into smaller organisms (<150 LOC each) -'use client' - -import { forwardRef, ReactNode } from 'react' -import { - Pagination as MuiPagination, - PaginationItem, - Box, - IconButton, - Typography, - Select, - MenuItem, - FormControl, - SelectChangeEvent, -} from '@mui/material' -import ChevronLeftIcon from '@mui/icons-material/ChevronLeft' -import ChevronRightIcon from '@mui/icons-material/ChevronRight' -import FirstPageIcon from '@mui/icons-material/FirstPage' -import LastPageIcon from '@mui/icons-material/LastPage' - -// Pagination Root -interface PaginationProps { - count: number - page: number - onChange: (page: number) => void - siblingCount?: number - boundaryCount?: number - showFirstButton?: boolean - showLastButton?: boolean - disabled?: boolean - size?: 'small' | 'medium' | 'large' - variant?: 'text' | 'outlined' - shape?: 'circular' | 'rounded' - color?: 'primary' | 'secondary' | 'standard' -} - -const Pagination = forwardRef( - ({ - count, - page, - onChange, - siblingCount = 1, - boundaryCount = 1, - showFirstButton = false, - showLastButton = false, - disabled = false, - size = 'medium', - variant = 'outlined', - shape = 'rounded', - color = 'primary', - ...props - }, ref) => { - return ( - onChange(newPage)} - siblingCount={siblingCount} - boundaryCount={boundaryCount} - showFirstButton={showFirstButton} - showLastButton={showLastButton} - disabled={disabled} - size={size} - variant={variant} - shape={shape} - color={color} - {...props} - /> - ) - } -) -Pagination.displayName = 'Pagination' - -// Simplified Pagination (Previous/Next only) -interface SimplePaginationProps { - hasPrevious: boolean - hasNext: boolean - onPrevious: () => void - onNext: () => void - previousLabel?: string - nextLabel?: string - disabled?: boolean -} - -const SimplePagination = forwardRef( - ({ - hasPrevious, - hasNext, - onPrevious, - onNext, - previousLabel = 'Previous', - nextLabel = 'Next', - disabled = false, - ...props - }, ref) => { - return ( - - - - - {previousLabel} - - - - - {nextLabel} - - - - - ) - } -) -SimplePagination.displayName = 'SimplePagination' - -// Table Pagination (with page size selector) -interface TablePaginationProps { - count: number - page: number - pageSize: number - pageSizeOptions?: number[] - onPageChange: (page: number) => void - onPageSizeChange: (pageSize: number) => void - showFirstLastButtons?: boolean - disabled?: boolean -} - -const TablePagination = forwardRef( - ({ - count, - page, - pageSize, - pageSizeOptions = [10, 25, 50, 100], - onPageChange, - onPageSizeChange, - showFirstLastButtons = true, - disabled = false, - ...props - }, ref) => { - const totalPages = Math.ceil(count / pageSize) - const startItem = (page - 1) * pageSize + 1 - const endItem = Math.min(page * pageSize, count) - - const handlePageSizeChange = (event: SelectChangeEvent) => { - onPageSizeChange(Number(event.target.value)) - } - - return ( - - - - Rows per page: - - - - - - - - {count === 0 ? '0' : `${startItem}-${endItem}`} of {count} - - - - {showFirstLastButtons && ( - onPageChange(1)} - disabled={disabled || page === 1} - size="small" - > - - - )} - onPageChange(page - 1)} - disabled={disabled || page === 1} - size="small" - > - - - onPageChange(page + 1)} - disabled={disabled || page === totalPages} - size="small" - > - - - {showFirstLastButtons && ( - onPageChange(totalPages)} - disabled={disabled || page === totalPages} - size="small" - > - - - )} - - - ) - } -) -TablePagination.displayName = 'TablePagination' - -// PaginationContent - wrapper for custom pagination content -interface PaginationContentProps { - children: ReactNode -} - -const PaginationContent = forwardRef( - ({ children, ...props }, ref) => { - return ( - - {children} - - ) - } -) -PaginationContent.displayName = 'PaginationContent' - -// PaginationItem wrapper -interface PaginationItemWrapperProps { - children: ReactNode -} - -const PaginationItemWrapper = forwardRef( - ({ children, ...props }, ref) => { - return ( - - {children} - - ) - } -) -PaginationItemWrapper.displayName = 'PaginationItem' - -// PaginationLink -interface PaginationLinkProps { - children: ReactNode - onClick?: () => void - isActive?: boolean - disabled?: boolean - size?: 'small' | 'medium' | 'large' -} - -const PaginationLink = forwardRef( - ({ children, onClick, isActive = false, disabled = false, size = 'medium', ...props }, ref) => { - const sizeMap = { - small: { minWidth: 28, height: 28 }, - medium: { minWidth: 36, height: 36 }, - large: { minWidth: 44, height: 44 }, - } - - return ( - - {children} - - ) - } -) -PaginationLink.displayName = 'PaginationLink' - -// Pagination Ellipsis -const PaginationEllipsis = forwardRef>( - (props, ref) => { - return ( - - ... - - ) - } -) -PaginationEllipsis.displayName = 'PaginationEllipsis' - -// Previous/Next buttons -const PaginationPrevious = forwardRef>( - (props, ref) => { - return ( - - - - ) - } -) -PaginationPrevious.displayName = 'PaginationPrevious' - -const PaginationNext = forwardRef>( - (props, ref) => { - return ( - - - - ) - } -) -PaginationNext.displayName = 'PaginationNext' - -export { - Pagination, - SimplePagination, - TablePagination, - PaginationContent, - PaginationItemWrapper as PaginationItem, - PaginationLink, - PaginationEllipsis, - PaginationPrevious, - PaginationNext, -} diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/Pagination.test.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/Pagination.test.tsx new file mode 100644 index 000000000..940c0e58a --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/Pagination.test.tsx @@ -0,0 +1,122 @@ +import { fireEvent, render, screen } from '@testing-library/react' +import { describe, expect, it, vi } from 'vitest' +import { + Pagination, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, + SimplePagination, + TablePagination, +} from './index' + +describe('Pagination components', () => { + it('triggers onChange for root Pagination', () => { + const handleChange = vi.fn() + render() + + fireEvent.click(screen.getByRole('button', { name: 'Go to page 2' })) + + expect(handleChange).toHaveBeenCalledWith(2) + }) + + it('handles SimplePagination controls', () => { + const onPrevious = vi.fn() + const onNext = vi.fn() + render( + + ) + + expect(screen.getByText('Prev').closest('button')?.disabled).toBe(true) + fireEvent.click(screen.getByText('Next')) + + expect(onNext).toHaveBeenCalled() + }) + + it('navigates TablePagination pages', () => { + const onPageChange = vi.fn() + const onPageSizeChange = vi.fn() + render( + + ) + + expect(screen.getByText('11-20 of 30')).toBeDefined() + + fireEvent.click(screen.getByRole('button', { name: 'Go to next page' })) + + expect(onPageChange).toHaveBeenCalledWith(3) + }) + + it('renders content wrappers', () => { + render( + + + 1 + + + + + + ) + + expect(screen.getByRole('list')).toBeDefined() + expect(screen.getAllByRole('listitem')).to.have.length(2) + }) + + it('renders link variants', () => { + const handleClick = vi.fn() + render( + + 5 + + ) + + fireEvent.click(screen.getByRole('button')) + + expect(handleClick).toHaveBeenCalled() + }) + + it('wraps icon links for previous and next', () => { + const onPrevious = vi.fn() + const onNext = vi.fn() + render( + + + + + + + + + ) + + const buttons = screen.getAllByRole('button') + fireEvent.click(buttons[0]) + fireEvent.click(buttons[1]) + + expect(onPrevious).toHaveBeenCalled() + expect(onNext).toHaveBeenCalled() + }) + + it('renders ellipsis marker', () => { + render() + + expect(screen.getByText('...')).toBeDefined() + }) +}) diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationContent.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationContent.tsx new file mode 100644 index 000000000..4d5a63d18 --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationContent.tsx @@ -0,0 +1,49 @@ +'use client' + +import { forwardRef, ReactNode } from 'react' +import { Box } from '@mui/material' + +interface PaginationContentProps { + children: ReactNode +} + +interface PaginationItemWrapperProps { + children: ReactNode +} + +const PaginationContent = forwardRef( + ({ children, ...props }, ref) => { + return ( + + {children} + + ) + } +) +PaginationContent.displayName = 'PaginationContent' + +const PaginationItem = forwardRef( + ({ children, ...props }, ref) => { + return ( + + {children} + + ) + } +) +PaginationItem.displayName = 'PaginationItem' + +export { PaginationContent, PaginationItem } +export type { PaginationContentProps, PaginationItemWrapperProps } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationEllipsis.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationEllipsis.tsx new file mode 100644 index 000000000..7719315ae --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationEllipsis.tsx @@ -0,0 +1,27 @@ +'use client' + +import { forwardRef } from 'react' +import { Box } from '@mui/material' + +const PaginationEllipsis = forwardRef>((props, ref) => { + return ( + + ... + + ) +}) +PaginationEllipsis.displayName = 'PaginationEllipsis' + +export { PaginationEllipsis } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationLink.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationLink.tsx new file mode 100644 index 000000000..4ee10fde6 --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationLink.tsx @@ -0,0 +1,35 @@ +'use client' + +import { forwardRef } from 'react' +import { IconButton } from '@mui/material' +import { paginationSizeMap, type PaginationLinkProps } from './paginationUtils' + +const PaginationLink = forwardRef( + ({ children, onClick, isActive = false, disabled = false, size = 'medium', ...props }, ref) => { + return ( + + {children} + + ) + } +) +PaginationLink.displayName = 'PaginationLink' + +export { PaginationLink } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationNext.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationNext.tsx new file mode 100644 index 000000000..d5ab34c71 --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationNext.tsx @@ -0,0 +1,18 @@ +'use client' + +import { forwardRef } from 'react' +import { PaginationLink } from './PaginationLink' +import { NextIcon, type PaginationLinkProps } from './paginationUtils' + +const PaginationNext = forwardRef>( + (props, ref) => { + return ( + + + + ) + } +) +PaginationNext.displayName = 'PaginationNext' + +export { PaginationNext } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationPrevious.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationPrevious.tsx new file mode 100644 index 000000000..60633050e --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationPrevious.tsx @@ -0,0 +1,18 @@ +'use client' + +import { forwardRef } from 'react' +import { PaginationLink } from './PaginationLink' +import { PreviousIcon, type PaginationLinkProps } from './paginationUtils' + +const PaginationPrevious = forwardRef>( + (props, ref) => { + return ( + + + + ) + } +) +PaginationPrevious.displayName = 'PaginationPrevious' + +export { PaginationPrevious } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationRoot.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationRoot.tsx new file mode 100644 index 000000000..ed09e923e --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/PaginationRoot.tsx @@ -0,0 +1,63 @@ +'use client' + +import { forwardRef } from 'react' +import { Pagination as MuiPagination } from '@mui/material' + +interface PaginationProps { + count: number + page: number + onChange: (page: number) => void + siblingCount?: number + boundaryCount?: number + showFirstButton?: boolean + showLastButton?: boolean + disabled?: boolean + size?: 'small' | 'medium' | 'large' + variant?: 'text' | 'outlined' + shape?: 'circular' | 'rounded' + color?: 'primary' | 'secondary' | 'standard' +} + +const Pagination = forwardRef( + ( + { + count, + page, + onChange, + siblingCount = 1, + boundaryCount = 1, + showFirstButton = false, + showLastButton = false, + disabled = false, + size = 'medium', + variant = 'outlined', + shape = 'rounded', + color = 'primary', + ...props + }, + ref + ) => { + return ( + onChange(newPage)} + siblingCount={siblingCount} + boundaryCount={boundaryCount} + showFirstButton={showFirstButton} + showLastButton={showLastButton} + disabled={disabled} + size={size} + variant={variant} + shape={shape} + color={color} + {...props} + /> + ) + } +) +Pagination.displayName = 'Pagination' + +export { Pagination } +export type { PaginationProps } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/SimplePagination.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/SimplePagination.tsx new file mode 100644 index 000000000..c59ce613f --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/SimplePagination.tsx @@ -0,0 +1,89 @@ +'use client' + +import { forwardRef } from 'react' +import { Box, IconButton, Typography } from '@mui/material' +import { NextIcon, PreviousIcon } from './paginationUtils' + +interface SimplePaginationProps { + hasPrevious: boolean + hasNext: boolean + onPrevious: () => void + onNext: () => void + previousLabel?: string + nextLabel?: string + disabled?: boolean +} + +const SimplePagination = forwardRef( + ( + { + hasPrevious, + hasNext, + onPrevious, + onNext, + previousLabel = 'Previous', + nextLabel = 'Next', + disabled = false, + ...props + }, + ref + ) => { + return ( + + + + + {previousLabel} + + + + + {nextLabel} + + + + + ) + } +) +SimplePagination.displayName = 'SimplePagination' + +export { SimplePagination } +export type { SimplePaginationProps } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/TablePagination.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/TablePagination.tsx new file mode 100644 index 000000000..32ad395f1 --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/TablePagination.tsx @@ -0,0 +1,128 @@ +'use client' + +import { forwardRef } from 'react' +import { + Box, + IconButton, + Typography, + Select, + MenuItem, + FormControl, + SelectChangeEvent, +} from '@mui/material' +import FirstPageIcon from '@mui/icons-material/FirstPage' +import LastPageIcon from '@mui/icons-material/LastPage' +import { NextIcon, PreviousIcon } from './paginationUtils' + +interface TablePaginationProps { + count: number + page: number + pageSize: number + pageSizeOptions?: number[] + onPageChange: (page: number) => void + onPageSizeChange: (pageSize: number) => void + showFirstLastButtons?: boolean + disabled?: boolean +} + +const TablePagination = forwardRef( + ( + { + count, + page, + pageSize, + pageSizeOptions = [10, 25, 50, 100], + onPageChange, + onPageSizeChange, + showFirstLastButtons = true, + disabled = false, + ...props + }, + ref + ) => { + const totalPages = Math.ceil(count / pageSize) + const startItem = (page - 1) * pageSize + 1 + const endItem = Math.min(page * pageSize, count) + + const handlePageSizeChange = (event: SelectChangeEvent) => { + onPageSizeChange(Number(event.target.value)) + } + + return ( + + + + Rows per page: + + + + + + + + {count === 0 ? '0' : `${startItem}-${endItem}`} of {count} + + + + {showFirstLastButtons && ( + onPageChange(1)} + disabled={disabled || page === 1} + size="small" + aria-label="Go to first page" + > + + + )} + onPageChange(page - 1)} + disabled={disabled || page === 1} + size="small" + aria-label="Go to previous page" + > + + + onPageChange(page + 1)} + disabled={disabled || page === totalPages} + size="small" + aria-label="Go to next page" + > + + + {showFirstLastButtons && ( + onPageChange(totalPages)} + disabled={disabled || page === totalPages} + size="small" + aria-label="Go to last page" + > + + + )} + + + ) + } +) +TablePagination.displayName = 'TablePagination' + +export { TablePagination } +export type { TablePaginationProps } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/index.ts b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/index.ts new file mode 100644 index 000000000..b1c8f728b --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/index.ts @@ -0,0 +1,13 @@ +export { Pagination } from './PaginationRoot' +export type { PaginationProps } from './PaginationRoot' +export { SimplePagination } from './SimplePagination' +export type { SimplePaginationProps } from './SimplePagination' +export { TablePagination } from './TablePagination' +export type { TablePaginationProps } from './TablePagination' +export { PaginationContent, PaginationItem } from './PaginationContent' +export type { PaginationContentProps, PaginationItemWrapperProps } from './PaginationContent' +export { PaginationLink } from './PaginationLink' +export { PaginationEllipsis } from './PaginationEllipsis' +export { PaginationPrevious } from './PaginationPrevious' +export { PaginationNext } from './PaginationNext' +export type { PaginationLinkProps } from './paginationUtils' diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/pagination/paginationUtils.tsx b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/paginationUtils.tsx new file mode 100644 index 000000000..b94162b34 --- /dev/null +++ b/frontends/nextjs/src/components/ui/organisms/navigation/pagination/paginationUtils.tsx @@ -0,0 +1,24 @@ +import { ReactNode } from 'react' +import ChevronLeftIcon from '@mui/icons-material/ChevronLeft' +import ChevronRightIcon from '@mui/icons-material/ChevronRight' + +interface PaginationLinkProps { + children: ReactNode + onClick?: () => void + isActive?: boolean + disabled?: boolean + size?: 'small' | 'medium' | 'large' +} + +const paginationSizeMap = { + small: { minWidth: 28, height: 28 }, + medium: { minWidth: 36, height: 36 }, + large: { minWidth: 44, height: 44 }, +} + +const PreviousIcon = () => + +const NextIcon = () => + +export { paginationSizeMap, PreviousIcon, NextIcon } +export type { PaginationLinkProps } diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/navigationConfig.ts b/frontends/nextjs/src/components/ui/organisms/navigation/utils/navigationConfig.ts similarity index 100% rename from frontends/nextjs/src/components/ui/organisms/navigation/navigationConfig.ts rename to frontends/nextjs/src/components/ui/organisms/navigation/utils/navigationConfig.ts diff --git a/frontends/nextjs/src/components/ui/organisms/navigation/navigationHelpers.ts b/frontends/nextjs/src/components/ui/organisms/navigation/utils/navigationHelpers.ts similarity index 100% rename from frontends/nextjs/src/components/ui/organisms/navigation/navigationHelpers.ts rename to frontends/nextjs/src/components/ui/organisms/navigation/utils/navigationHelpers.ts