mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
Add pagination component
This commit is contained in:
@ -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>
|
||||||
|
64
components/RUA/RUAPagination.tsx
Normal file
64
components/RUA/RUAPagination.tsx
Normal 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;
|
@ -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;
|
|
@ -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[];
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user