-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
♻️ refactor(#167): 내 대시보드 페이지 서버 사이드 렌더링 적용 #199
Changes from 3 commits
7be8f0d
8b953d1
bd0ef9f
6e1df7c
4d719c5
f54fde4
1790ab1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,23 @@ | ||
import Image from 'next/image'; | ||
import Link from 'next/link'; | ||
import { useState } from 'react'; | ||
import { useEffect, useState } from 'react'; | ||
|
||
import Pagination from '@/components/Pagination'; | ||
import useFetchData from '@/hooks/useFetchData'; | ||
import useModal from '@/hooks/useModal'; | ||
import { getDashboardsList } from '@/services/getService'; | ||
import { DashboardsResponse } from '@/types/Dashboard.interface'; | ||
|
||
export default function DashboardList() { | ||
interface DashboardListProps { | ||
initialDashboard: DashboardsResponse; | ||
} | ||
|
||
export default function DashboardList({ initialDashboard }: DashboardListProps) { | ||
const [currentChunk, setCurrentChunk] = useState<number>(1); | ||
const { openNewDashboardModal } = useModal(); | ||
const [dashboardData, setDashboards] = useState<DashboardsResponse>(initialDashboard); | ||
|
||
// 대시보드 데이터를 가져오는 커스텀 훅 사용 | ||
const { | ||
data: dashboardResponse, | ||
error, | ||
|
@@ -20,7 +26,15 @@ export default function DashboardList() { | |
getDashboardsList('pagination', currentChunk, 5), | ||
); | ||
|
||
const totalPage = dashboardResponse ? Math.max(1, Math.ceil(dashboardResponse.totalCount / 5)) : 1; | ||
// 총 페이지 수 계산 | ||
const totalPage = dashboardData?.totalCount ? Math.max(1, Math.ceil(dashboardData.totalCount / 5)) : 1; | ||
|
||
// 대시보드 데이터가 변경될 때 상태 업데이트 | ||
useEffect(() => { | ||
if (dashboardResponse) { | ||
setDashboards(dashboardResponse); | ||
} | ||
}, [dashboardResponse]); | ||
|
||
if (error) { | ||
return ( | ||
|
@@ -31,41 +45,44 @@ export default function DashboardList() { | |
); | ||
} | ||
|
||
// 다음 페이지로 이동하는 함수 | ||
const handleNext = () => { | ||
if (currentChunk < totalPage) { | ||
setCurrentChunk((prev) => prev + 1); | ||
} | ||
}; | ||
|
||
// 이전 페이지로 이동하는 함수 | ||
const handlePrev = () => { | ||
if (currentChunk > 1) { | ||
setCurrentChunk((prev) => prev - 1); | ||
} | ||
}; | ||
|
||
if (!dashboardData) return null; | ||
|
||
return ( | ||
<section className='flex-col justify-between'> | ||
<ul className='grid max-w-[350px] grid-rows-1 gap-3 font-semibold text-black-33 md:min-h-[216px] md:max-w-full md:grid-cols-2 md:grid-rows-3 lg:min-h-[140px] lg:max-w-screen-lg lg:grid-cols-3'> | ||
{/* 새로운 대시보드 생성 버튼 */} | ||
<li className='h-12 w-full rounded-lg border border-gray-d9 bg-white md:h-16'> | ||
<button className='btn-violet-light size-full gap-4' type='button' onClick={() => openNewDashboardModal()}> | ||
새로운 대시보드 | ||
<Image src={'/icons/plus-filled.svg'} alt='plus' width={22} height={22} /> | ||
</button> | ||
</li> | ||
{isLoading ? ( | ||
<> | ||
{[...Array(5)].map((_, i) => ( | ||
{/* 대시보드 목록 표시 */} | ||
{isLoading && currentChunk !== 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 페이지가 1페이지면 스켈레톤을 안보이게 했습니다 |
||
? [...Array(5)].map((_, i) => ( | ||
<li key={i} className='h-12 w-full animate-pulse rounded-lg border border-gray-d9 bg-gray-fa md:h-16' /> | ||
))} | ||
</> | ||
) : ( | ||
<> | ||
{dashboardResponse?.dashboards.map((dashboard) => ( | ||
)) | ||
: dashboardData.dashboards.map((dashboard) => ( | ||
<li className='h-12 w-full rounded-lg border border-gray-d9 bg-white md:h-16' key={dashboard.id}> | ||
<Link href={`/dashboard/${dashboard.id}`} className={'btn-violet-light size-full rounded-md px-5'}> | ||
<Link href={`/dashboard/${dashboard.id}`} className='btn-violet-light size-full rounded-md px-5'> | ||
<div className='flex size-full items-center'> | ||
<div className='rounded-full p-1' style={{ backgroundColor: dashboard.color }} /> | ||
<div className='mx-4 h-[28px] grow overflow-hidden text-ellipsis text-lg font-medium'> | ||
<p className={`size-full`}>{dashboard.title}</p> | ||
<p className='size-full'>{dashboard.title}</p> | ||
</div> | ||
{dashboard.createdByMe && ( | ||
<Image src={'/icons/crown.svg'} className='mr-3' alt='my' width={20} height={16} /> | ||
|
@@ -75,9 +92,7 @@ export default function DashboardList() { | |
</Link> | ||
</li> | ||
))} | ||
</> | ||
)} | ||
|
||
{/* 페이지네이션 */} | ||
<div className='md:col-span-2 lg:col-span-3 lg:row-start-3'> | ||
<Pagination | ||
currentChunk={currentChunk} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import { useMutation } from '@tanstack/react-query'; | ||
import { AxiosError } from 'axios'; | ||
import { setCookie } from 'cookies-next'; | ||
import { useDispatch } from 'react-redux'; | ||
|
||
import { postSignIn } from '@/services/postService'; | ||
|
@@ -22,6 +23,7 @@ export const useSignIn = () => { | |
onSuccess: (data) => { | ||
dispatch(setUser(data)); | ||
dispatch(isLoading(false)); | ||
setCookie('token', data.accessToken); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로그인 할 때 쿠키로 액세스 토큰을 저장합니다 |
||
}, | ||
onMutate: async () => { | ||
dispatch(isLoading(true)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { deleteCookie } from 'cookies-next'; | ||
import { useRouter } from 'next/router'; | ||
import { MouseEventHandler, useEffect, useRef, useState } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
|
@@ -29,6 +30,7 @@ const useUserDropdown = () => { | |
const handleLogoutClick: MouseEventHandler<HTMLButtonElement> = (e) => { | ||
e.stopPropagation(); | ||
dispatch(clearUser()); | ||
deleteCookie('token'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로그아웃 할 때 쿠키를 제거합니다( 여기에 추가하는게 맞나요? ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! 테스트하니 잘 지워지네요 |
||
setIsOpen(false); | ||
router.push('/'); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isInit state 뺐습니다 데이터를 새로 불러와서 집어넣어도 생긴게 동일해서 깜빡이거나 하지 않더라구요
초기값이 없으면 어짜피 얘도 없으니 그에 대한 처리도 안해줬습니다