Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/layout/footer/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ const Footer = () => {
©codeit - 2023
</div>
<div className='order-1 flex gap-[30px] font-normal text-gray-500'>
<Link href={'/'} className='text-body-s hover:text-gray-300 tablet:text-body-m'>
<Link href={'/'} className='text-body-s hover:text-gray-700 tablet:text-body-m'>
Privacy Policy
</Link>
<Link href={'/'} className='text-body-s hover:text-gray-300 tablet:text-body-m'>
<Link href={'/'} className='text-body-s hover:text-gray-700 tablet:text-body-m'>
FAQ
</Link>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/layout/footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Footer } from './footer';
1 change: 1 addition & 0 deletions src/components/layout/frame/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Frame } from './frame';
2 changes: 2 additions & 0 deletions src/components/layout/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { Container, Wrapper } from './container';
export { Footer } from './footer';
export { Frame } from './frame';
export { Header } from './header';
1 change: 1 addition & 0 deletions src/components/ui/pagination/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Pagination } from './pagination';
74 changes: 74 additions & 0 deletions src/components/ui/pagination/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Icon } from '@/components/ui';
import { useEffect, useState } from 'react';

const PAGE_GROUP_SIZE = 7;

interface PaginationProps {
totalItems: number;
currentPage: number;
itemsPerPage: number;
onPageChange: (page: number) => void;
}
// totalItems 는 API 통신 시 Response 로 받는 """count""" 부모로부터 넘겨주기!

const Pagination = ({ totalItems, currentPage, itemsPerPage, onPageChange }: PaginationProps) => {
const [pageGroup, setPageGroup] = useState(0);

const totalPages = totalItems ? Math.ceil(totalItems / itemsPerPage) : 0;

useEffect(() => {
const newGroup = Math.floor((currentPage - 1) / PAGE_GROUP_SIZE);
setPageGroup(newGroup);
}, [currentPage]);

if (totalPages < 1) return null;

const startPage = pageGroup * PAGE_GROUP_SIZE + 1;
const endPage = Math.min(startPage + PAGE_GROUP_SIZE - 1, totalPages);
const pageNumbers = Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i);
const isPrevDisabled = pageGroup === 0;
const isNextDisabled = (pageGroup + 1) * PAGE_GROUP_SIZE >= totalPages;

return (
<>
<div className='flex h-14 items-center justify-center bg-white tablet:h-16'>
<div className='flex h-8 items-center justify-center gap-[2px] px-3 py-2 tablet:h-10'>
<button className='flex items-center justify-center'>
<Icon
className={`h-5 w-5 ${isPrevDisabled ? 'cursor-default bg-gray-400' : 'cursor-pointer'}`}
onClick={() => !isPrevDisabled && setPageGroup(prev => Math.max(prev - 1, 0))}
iconName='chevronLeft'
ariaLabel='이전'
/>
</button>
{pageNumbers.map(page => (
<button
key={page}
onClick={() => onPageChange(page)}
className={
page === currentPage
? 'h-8 w-8 rounded bg-red-300 text-caption text-white tablet:text-body-s'
: 'h-8 w-8 text-caption tablet:text-body-s'
}
>
{page}
</button>
))}
<button className='flex items-center justify-center'>
<Icon
className={`h-5 w-5 ${isNextDisabled ? 'cursor-default bg-gray-400' : 'cursor-pointer'}`}
onClick={() =>
!isNextDisabled &&
setPageGroup(prev => ((prev + 1) * PAGE_GROUP_SIZE < totalPages ? prev + 1 : prev))
}
iconName='chevronRight'
ariaLabel='이후'
/>
</button>
</div>
</div>
</>
);
};

export default Pagination;
2 changes: 1 addition & 1 deletion src/context/appProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import AuthProvider from './authProvider';
import ToastProvider from './toastContext/toastContext';
import { ToastProvider } from './toastContext';

const AppProvider = ({ children }: { children: ReactNode }) => {
return (
Expand Down
1 change: 1 addition & 0 deletions src/context/toastContext/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ToastProvider } from './toastContext';
4 changes: 2 additions & 2 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Header, Wrapper } from '@/components/layout';
import Footer from '@/components/layout/footer/footer';
import { Footer, Header, Wrapper } from '@/components/layout';

import AppProvider from '@/context/appProvider';

import '@/styles/fonts.css';
Expand Down