Skip to content

Commit 0cb04ef

Browse files
committed
✨ feat: 스켈레톤 ui 추가 잘못된 id 404로 이동
1 parent 4ae7398 commit 0cb04ef

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

src/app/(crew)/crew/detail/[id]/_components/detail-crew-container.tsx

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import { useEffect, useState } from 'react';
44
import { toast } from 'react-toastify';
55
import { useRouter } from 'next/navigation';
6-
import { Loader } from '@mantine/core';
76
import { useDisclosure } from '@mantine/hooks';
87
import { cancelCrew, joinCrew, leaveCrew } from '@/src/_apis/crew/crew-detail-apis';
98
import { useUser } from '@/src/_queries/auth/user-queries';
109
import { useGetCrewDetailQuery } from '@/src/_queries/crew/crew-detail-queries';
1110
import { ApiError } from '@/src/utils/api';
11+
import Button from '@/src/components/common/input/button';
1212
import ConfirmCancelModal from '@/src/components/common/modal/confirm-cancel-modal';
13+
import CrewDetailSkeleton from '@/src/components/common/skeleton/crew-detail-skeleton';
1314
import { User } from '@/src/types/auth';
1415
import DetailCrewPresenter from './detail-crew-presenter';
1516

@@ -38,12 +39,8 @@ export default function DetailCrew({ id }: DetailCrewContainerProps) {
3839

3940
useEffect(() => {
4041
if (data) {
41-
// confirmed 상태 계산
42-
if (data.participantCount !== undefined && data.totalCount !== undefined) {
43-
setIsConfirmed(data.participantCount === data.totalCount);
44-
}
42+
setIsConfirmed(data.participantCount === data.totalCount);
4543

46-
// Captain 및 멤버 여부 확인 (currentUserId 필요)
4744
if (currentUserId) {
4845
const captain = data.crewMembers.find((member) => member.captain);
4946
const memberExists = data.crewMembers.some((member) => member.id === currentUserId);
@@ -114,29 +111,35 @@ export default function DetailCrew({ id }: DetailCrewContainerProps) {
114111
});
115112
};
116113

117-
// TODO: 로딩, 에러처리 추후 개선
118114
if (isLoading) {
119-
return <Loader />;
115+
return <CrewDetailSkeleton />;
120116
}
121117

122-
// TODO: 추후 404페이지로 이동시키기
123-
if (fetchError) {
118+
const renderErrorState = (message: string, actionLabel: string, action: () => void) => (
119+
<div className="flex h-screen flex-col items-center justify-center">
120+
<p className="mb-4 text-gray-500">{message} 😞</p>
121+
<Button className="btn-filled" onClick={action}>
122+
{actionLabel}
123+
</Button>
124+
</div>
125+
);
126+
127+
if (fetchError || !data) {
124128
if (fetchError instanceof ApiError) {
125-
try {
126-
const errorData = JSON.parse(fetchError.message);
127-
128-
if (errorData.status === 'NOT_FOUND') {
129-
return <p>크루 정보를 찾을 수 없습니다</p>;
130-
}
131-
} catch (parseError) {
132-
return <p>{`Error ${fetchError.message}`}</p>;
129+
if (fetchError.status === 404) {
130+
router.push('/404');
131+
return null;
133132
}
133+
toast.error(fetchError.message || '🚫 에러가 발생했습니다.');
134+
} else if (fetchError) {
135+
toast.error('🚫 데이터 통신에 실패했습니다.');
134136
}
135-
return <p>데이터 통신에 실패했습니다.</p>;
136-
}
137137

138-
if (!data) {
139-
return <p>데이터를 불러올 수 없습니다.</p>;
138+
const errorMessage = fetchError
139+
? '데이터를 불러오는 데 실패했습니다.'
140+
: '데이터를 불러올 수 없습니다.';
141+
142+
return renderErrorState(errorMessage, '다시 시도', refetch);
140143
}
141144

142145
return (

0 commit comments

Comments
 (0)