fix: pagination

This commit is contained in:
Nevo David 2025-12-27 10:24:11 +07:00
parent 6f889d42c8
commit 90da9d4aff
1 changed files with 75 additions and 28 deletions

View File

@ -20,9 +20,7 @@ import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.v
import EventEmitter from 'events';
import clsx from 'clsx';
import { VideoFrame } from '@gitroom/react/helpers/video.frame';
import {
useUppyUploader,
} from '@gitroom/frontend/components/media/new.uploader';
import { useUppyUploader } from '@gitroom/frontend/components/media/new.uploader';
import dynamic from 'next/dynamic';
import { useUser } from '@gitroom/frontend/components/layout/user.context';
import { AiImage } from '@gitroom/frontend/components/launches/ai.image';
@ -31,9 +29,7 @@ import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
import { useT } from '@gitroom/react/translation/get.transation.service.client';
import { ThirdPartyMedia } from '@gitroom/frontend/components/third-parties/third-party.media';
import { ReactSortable } from 'react-sortablejs';
import {
MediaComponentInner,
} from '@gitroom/frontend/components/launches/helpers/media.settings.component';
import { MediaComponentInner } from '@gitroom/frontend/components/launches/helpers/media.settings.component';
import { AiVideo } from '@gitroom/frontend/components/launches/ai.video';
import { useModals } from '@gitroom/frontend/components/layout/new-modal';
import { Dashboard } from '@uppy/react';
@ -62,14 +58,59 @@ export const Pagination: FC<{
const t = useT();
const { current, totalPages, setPage } = props;
const totalPagesList = useMemo(() => {
return Array.from(
{
length: totalPages,
},
(_, i) => i
);
}, [totalPages]);
const paginationItems = useMemo(() => {
// Convert to 1-based for algorithm (current is 0-based)
const c = current + 1;
const m = totalPages;
// If total pages <= 10, show all pages
if (m <= 10) {
return Array.from({ length: m }, (_, i) => i + 1);
}
const delta = 3;
const left = c - delta;
const right = c + delta + 1;
const range: number[] = [];
const rangeWithDots: (number | '...')[] = [];
let l: number | undefined;
// Build the range of pages to show
for (let i = 1; i <= m; i++) {
if (i === 1 || i === m || (i >= left && i < right)) {
range.push(i);
}
}
// Add dots where there are gaps
for (const i of range) {
if (l !== undefined) {
if (i - l === 2) {
rangeWithDots.push(l + 1);
} else if (i - l !== 1) {
rangeWithDots.push('...');
}
}
rangeWithDots.push(i);
l = i;
}
// Limit to maximum 10 items by trimming pages near edges if needed
while (rangeWithDots.length > 10) {
const currentIndex = rangeWithDots.findIndex((item) => item === c);
if (currentIndex !== -1 && currentIndex > rangeWithDots.length / 2) {
// Current is in second half, remove one item from start side
rangeWithDots.splice(2, 1);
} else {
// Current is in first half, remove one item from end side
rangeWithDots.splice(-3, 1);
}
}
return rangeWithDots;
}, [current, totalPages]);
return (
<ul className="flex flex-row items-center gap-1 justify-center mt-[15px]">
<li className={clsx(current === 0 && 'opacity-20 pointer-events-none')}>
@ -82,20 +123,26 @@ export const Pagination: FC<{
<span>{t('previous', 'Previous')}</span>
</div>
</li>
{totalPagesList.map((page) => (
<li key={page} className="">
<div
aria-current="page"
onClick={() => setPage(page)}
className={clsx(
'cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border hover:bg-forth h-10 w-10 hover:text-white border-newBorder',
current === page
? 'bg-forth !text-white'
: 'text-textColor hover:text-white'
)}
>
{page + 1}
</div>
{paginationItems.map((item, index) => (
<li key={index}>
{item === '...' ? (
<span className="inline-flex items-center justify-center h-10 w-10 text-textColor select-none">
...
</span>
) : (
<div
aria-current="page"
onClick={() => setPage(item - 1)}
className={clsx(
'cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border hover:bg-forth h-10 w-10 hover:text-white border-newBorder',
current === item - 1
? 'bg-forth !text-white'
: 'text-textColor hover:text-white'
)}
>
{item}
</div>
)}
</li>
))}
<li