Add pagination component

* add outline box shadow
* add pagination pages
* add RUA button
This commit is contained in:
DefectingCat
2022-01-17 12:32:32 +08:00
parent 14e606ddb4
commit bff68dec9b
7 changed files with 139 additions and 7 deletions

45
components/Pagination.tsx Normal file
View File

@ -0,0 +1,45 @@
import Link from 'next/link';
import { FC } from 'react';
import cn from 'classnames';
import dynamic from 'next/dynamic';
const Button = dynamic(() => import('components/RUA/RUAButton'));
interface Props {
allPages: number;
num?: string;
}
const Pagination: FC<Props> = ({ allPages, num }) => {
const startIndex = Number(num);
const nextPage = startIndex != allPages ? `/page/${startIndex + 1}` : '/';
const prevPage = startIndex > 2 ? `/page/${startIndex - 1}` : '/';
return (
<>
<div className="flex items-center text-gray-600 justify-between text-lg font-semibold">
{startIndex > 1 && (
<Link href={prevPage} passHref>
<a>
<Button></Button>
</a>
</Link>
)}
<span>
{num} / {allPages}
</span>
{startIndex !== allPages && (
<Link href={nextPage} passHref>
<a>
<Button></Button>
</a>
</Link>
)}
</div>
</>
);
};
export default Pagination;

View File

@ -0,0 +1,24 @@
import { FC } from 'react';
import cn from 'classnames';
interface Props {
allPages: number;
num?: string;
}
const RUAButton: FC = ({ children }) => {
return (
<>
<button
className={cn(
'rounded-lg bg-white px-6 py-3 font-semibold',
'focus:shadow-outline active:bg-gray-100 transition-all'
)}
>
{children}
</button>
</>
);
};
export default RUAButton;

View File

@ -27,13 +27,10 @@ const SearchBox: FC = () => {
setValue(e.target.value);
}, []);
const handleSearch: KeyboardEventHandler<HTMLInputElement> = useCallback(
(e) => {
if (e.key !== 'Enter') return;
router.push({ pathname: 'search', query: { q: value } });
},
[router, value]
);
const handleSearch: KeyboardEventHandler<HTMLInputElement> = (e) => {
if (e.key !== 'Enter') return;
router.push({ pathname: 'search', query: { q: value } });
};
useEffect(() => {
window.addEventListener('keyup', handleSlash);

View File

@ -7,6 +7,7 @@ import { InferGetStaticPropsType } from 'next';
const MainLayout = dynamic(() => import('layouts/MainLayout'));
const PostCard = dynamic(() => import('components/PostCard'));
const Pagination = dynamic(() => import('components/Pagination'));
const Home = ({
allPages,
@ -21,6 +22,8 @@ const Home = ({
{postDatas.map((post) => (
<PostCard key={post.id} {...post} />
))}
<Pagination allPages={allPages} num="1" />
</>
);
};

55
pages/page/[num].tsx Normal file
View File

@ -0,0 +1,55 @@
import { ReactElement } from 'react';
import dynamic from 'next/dynamic';
import Head from 'next/head';
import { getAllPostNum, getPagingData, PagingData } from 'lib/posts';
import { GetStaticProps, InferGetStaticPropsType } from 'next';
const MainLayout = dynamic(() => import('layouts/MainLayout'));
const PostCard = dynamic(() => import('components/PostCard'));
const Pagination = dynamic(() => import('components/Pagination'));
const Page = ({
num,
allPages,
postDatas,
}: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
<>
<Head>
<title>RUA - Home</title>
</Head>
{postDatas.map((post) => (
<PostCard key={post.id} {...post} />
))}
<Pagination allPages={allPages} num={num} />
</>
);
};
export function getStaticPaths() {
return {
paths: getAllPostNum(),
fallback: false,
};
}
export const getStaticProps: GetStaticProps<{ num?: string } & PagingData> = ({
params,
}) => {
const num = params?.num?.toString();
return {
props: {
num,
...getPagingData(num),
},
};
};
Page.getLayout = function getLayout(page: ReactElement) {
return <MainLayout>{page}</MainLayout>;
};
export default Page;

View File

@ -1,6 +1,7 @@
import { useRouter } from 'next/router';
import { ReactElement } from 'react';
import dynamic from 'next/dynamic';
import Head from 'next/head';
const MainLayout = dynamic(() => import('layouts/MainLayout'));
@ -10,6 +11,10 @@ const Search = () => {
return (
<>
<Head>
<title>RUA - Search</title>
</Head>
<code>{q}</code>
</>
);

View File

@ -11,6 +11,9 @@ module.exports = {
gray: 'rgba(245,247,250)',
},
},
boxShadow: {
outline: '0 0 0 3px rgba(83, 220, 246, 0.6)',
},
},
},
plugins: [],