fix: pagination
This commit is contained in:
parent
6f889d42c8
commit
90da9d4aff
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue