Add pagination component

This commit is contained in:
DefectingCat
2022-08-23 13:50:37 +08:00
parent 5bcc2ecba8
commit 2f42e3fb90
5 changed files with 88 additions and 55 deletions

View File

@ -1,11 +1,14 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';
export type ButtonProps = { export type ButtonProps = {
children: React.ReactNode; children: React.ReactNode;
disabled?: boolean; } & DetailedHTMLProps<
}; ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
>;
const Button = ({ children, disabled }: ButtonProps) => { const Button = ({ children, ...rest }: ButtonProps) => {
return ( return (
<> <>
<button <button
@ -13,7 +16,7 @@ const Button = ({ children, disabled }: ButtonProps) => {
'bg-white border border-transparent hover:border-gray-200', 'bg-white border border-transparent hover:border-gray-200',
'outline-none hover:bg-gray-50 focus:ring-4 dark:border-transparent', 'outline-none hover:bg-gray-50 focus:ring-4 dark:border-transparent',
'focus:ring-cyan-200 font-medium rounded-lg text-sm', 'focus:ring-cyan-200 font-medium rounded-lg text-sm',
'px-5 py-2.5 mr-2 mb-2 dark:bg-gray-800 dark:text-white ', 'px-5 py-2.5 dark:bg-gray-800 dark:text-white ',
'dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:ring-cyan-800', 'dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:ring-cyan-800',
'transition-all disabled:hover:bg-gray-200', 'transition-all disabled:hover:bg-gray-200',
'disabled:cursor-not-allowed disabled:dark:hover:bg-gray-700', 'disabled:cursor-not-allowed disabled:dark:hover:bg-gray-700',
@ -22,7 +25,7 @@ const Button = ({ children, disabled }: ButtonProps) => {
'dark:disabled:bg-gray-700 dark:disabled:text-gray-300', 'dark:disabled:bg-gray-700 dark:disabled:text-gray-300',
'disabled:dark:hover:border-transparent' 'disabled:dark:hover:border-transparent'
)} )}
disabled={disabled} {...rest}
> >
{children} {children}
</button> </button>

View File

@ -0,0 +1,64 @@
import dynamic from 'next/dynamic';
import Link from 'next/link';
const Button = dynamic(() => import('components/RUA/Button'));
type Props = {
hasPrev: boolean;
hasNext: boolean;
prevLink: string;
nextLink: string;
current?: number;
total?: number;
};
const RUAPagination = ({
hasPrev,
hasNext,
prevLink,
nextLink,
current,
total,
}: Props) => {
return (
<>
<nav>
<ul className="flex items-center justify-between -space-x-px">
<li>
{hasPrev ? (
<Link href={prevLink} passHref>
<a>
<Button>Prev</Button>
</a>
</Link>
) : (
<Button disabled>Prev</Button>
)}
</li>
{current != null && total != null && (
<li className="text-xl">
<span>{current}</span>
<span>/</span>
<span>{total}</span>
</li>
)}
<li>
{hasNext ? (
<Link href={nextLink} passHref>
<a>
<Button>Next</Button>
</a>
</Link>
) : (
<Button disabled>Next</Button>
)}
</li>
</ul>
</nav>
</>
);
};
export default RUAPagination;

View File

@ -1,48 +0,0 @@
import { pageSize } from 'lib/fetcher';
import dynamic from 'next/dynamic';
import Link from 'next/link';
const Button = dynamic(() => import('components/RUA/Button'));
type Props = {
pageSize: pageSize;
};
const Pagination = ({ pageSize }: Props) => {
const prev = Number(pageSize.prev);
const next = Number(pageSize.next);
return (
<>
<nav>
<ul className="flex justify-between -space-x-px">
<li>
{!!prev ? (
<Link href={prev === 1 ? `/gists/` : `/gists/${prev}`} passHref>
<a>
<Button>Prev</Button>
</a>
</Link>
) : (
<Button disabled>Prev</Button>
)}
</li>
<li>
{!!next ? (
<Link href={`/gists/${next}`} passHref>
<a>
<Button>Next</Button>
</a>
</Link>
) : (
<Button disabled>Next</Button>
)}
</li>
</ul>
</nav>
</>
);
};
export default Pagination;

View File

@ -17,6 +17,9 @@ export type GistData = {
description: string | null; description: string | null;
}; };
export type GetGists = { export type GetGists = {
/**
* { prev: null, next: '2', last: '5', first: null }
*/
pageSize: pageSize; pageSize: pageSize;
gists: GistData[]; gists: GistData[];
}; };

View File

@ -8,7 +8,7 @@ import { ReactElement } from 'react';
const MainLayout = dynamic(() => import('layouts/MainLayout')); const MainLayout = dynamic(() => import('layouts/MainLayout'));
const UserInfo = dynamic(() => import('components/gists/UserInfo')); const UserInfo = dynamic(() => import('components/gists/UserInfo'));
const FileContent = dynamic(() => import('components/gists/FileContent')); const FileContent = dynamic(() => import('components/gists/FileContent'));
const Pagination = dynamic(() => import('components/gists/Pagination')); const Pagination = dynamic(() => import('components/RUA/RUAPagination'));
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
@ -16,6 +16,10 @@ const Gists = ({
gists, gists,
user, user,
}: InferGetStaticPropsType<typeof getStaticProps>) => { }: InferGetStaticPropsType<typeof getStaticProps>) => {
const prev = Number(gists.pageSize.prev);
const next = Number(gists.pageSize.next);
const total = Number(gists.pageSize.last);
return ( return (
<> <>
<main className="max-w-5xl px-4 mx-auto lg:px-0"> <main className="max-w-5xl px-4 mx-auto lg:px-0">
@ -24,7 +28,14 @@ const Gists = ({
<div className="flex-1 py-4 overflow-hidden md:pl-8"> <div className="flex-1 py-4 overflow-hidden md:pl-8">
<FileContent gists={gists.gists} /> <FileContent gists={gists.gists} />
<Pagination pageSize={gists.pageSize} /> <Pagination
hasPrev={!!prev}
hasNext={!!next}
prevLink={prev === 1 ? `/gists/` : `/gists/${prev}`}
nextLink={`/gists/${next}`}
current={prev == null ? next - 1 : prev + 1}
total={total}
/>
</div> </div>
</div> </div>
</main> </main>