diff --git a/src/app/(with-header)/myprofile/_components/MyProfileContainer.tsx b/src/app/(with-header)/myprofile/_components/MyProfileContainer.tsx index 285bef5..f541656 100644 --- a/src/app/(with-header)/myprofile/_components/MyProfileContainer.tsx +++ b/src/app/(with-header)/myprofile/_components/MyProfileContainer.tsx @@ -4,30 +4,39 @@ import { useEffect, useState } from 'react'; import { fetchWithAuth } from '@/lib/auth'; import { MyProfile, MyProfileData } from './MyProfile'; import LoadingSpinner from '@/components/LoadingSpinner'; +import Refresh from '@/components/Refresh'; export default function MyProfileContainer() { const [profileData, setProfileData] = useState(); const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(''); const getUserData = async () => { + setError(''); try { setIsLoading(true); const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/users/me`); if (!response?.ok || response === null) { + setError('유저 데이터를 불러오는데 실패했습니다.'); return; } const data: MyProfileData = await response.json(); setProfileData(data); } catch (error) { - console.error('유저 정보를 불러오는 중 문제가 발생했습니다:', error); + if (error instanceof Error) { + setError(error.message); + } else { + setError('알 수 없는 오류가 발생했습니다.'); + } } finally { setIsLoading(false); } }; const upLoadImgFile = async (formData: FormData): Promise => { + setError(''); try { const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/images/upload`, { method: 'POST', @@ -35,18 +44,23 @@ export default function MyProfileContainer() { }); if (!response?.ok || response === null) { + setError('이미지를 업로드하는데 실패했습니다.'); return; } const data = await response.json(); return data.url as string; } catch (error) { - console.error('이미지 업로드 중 문제가 발생했습니다:', error); - return; + if (error instanceof Error) { + setError(error.message); + } else { + setError('알 수 없는 오류가 발생했습니다.'); + } } }; const upLoadUserData = async (image: string, nickname: string): Promise => { + setError(''); try { const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/users/me`, { method: 'PATCH', @@ -61,14 +75,18 @@ export default function MyProfileContainer() { } if (!response?.ok || response === null) { + setError('데이터를 업데이트 하는데 실패했습니다.'); return; } const result = await response.json(); return result; } catch (error) { - console.error('프로필 업로드 중 문제가 발생했습니다:', error); - return; + if (error instanceof Error) { + setError(error.message); + } else { + setError('알 수 없는 오류가 발생했습니다.'); + } } }; @@ -78,7 +96,16 @@ export default function MyProfileContainer() { if (isLoading) return ; - if (!profileData) return
; + if (!profileData || error) + return ( + + ); return ; } diff --git a/src/app/(with-header)/myprofile/_components/MyReviewListContainer.tsx b/src/app/(with-header)/myprofile/_components/MyReviewListContainer.tsx index 2517711..8aedc41 100644 --- a/src/app/(with-header)/myprofile/_components/MyReviewListContainer.tsx +++ b/src/app/(with-header)/myprofile/_components/MyReviewListContainer.tsx @@ -5,8 +5,9 @@ import { useCallback, useEffect, useState } from 'react'; import { fetchWithAuth } from '@/lib/auth'; import emptyData from '@/assets/icons/empty_review.svg'; import { MyReview, MyReviewResponse } from '@/types/review-data'; -import { MyReviewItem } from './MyReviewItem'; +import { MyReviewItem } from '@/app/(with-header)/myprofile/_components/MyReviewItem'; import LoadingSpinner from '@/components/LoadingSpinner'; +import Refresh from '@/components/Refresh'; export interface EditReviewData { rating: number; @@ -22,13 +23,16 @@ export interface EditReviewData { export default function MyReviewListContainer({ setDataCount }: { setDataCount: (value: number) => void }) { const [myReviewData, setMyReviewData] = useState([]); const [isLoading, setIsloading] = useState(true); + const [error, setError] = useState(''); const getMyReview = useCallback(async () => { + setError(''); try { setIsloading(true); const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/users/me/reviews?limit=30`); if (!response?.ok || response === null) { + setError('리뷰 데이터를 불러오는데 실패했습니다.'); return; } @@ -36,7 +40,11 @@ export default function MyReviewListContainer({ setDataCount }: { setDataCount: setMyReviewData(data.list); setDataCount(data.totalCount); } catch (error) { - console.error('리뷰를 불러오는 중 문제가 발생했습니다:', error); + if (error instanceof Error) { + setError(error.message); + } else { + setError('알 수 없는 오류가 발생했습니다.'); + } } finally { setIsloading(false); } @@ -63,9 +71,20 @@ export default function MyReviewListContainer({ setDataCount }: { setDataCount: if (isLoading) return ; + if (error) + return ( + + ); + if (myReviewData.length === 0) return ( -
+
데이터 없음

내가 등록한 후기가 없어요

diff --git a/src/app/(with-header)/myprofile/_components/MyWineListContainer.tsx b/src/app/(with-header)/myprofile/_components/MyWineListContainer.tsx index fd0dd41..ed56111 100644 --- a/src/app/(with-header)/myprofile/_components/MyWineListContainer.tsx +++ b/src/app/(with-header)/myprofile/_components/MyWineListContainer.tsx @@ -8,17 +8,21 @@ import emptyData from '@/assets/icons/empty_review.svg'; import WineCard from '@/components/WineCard'; import { WineDataProps } from './MyWIneKebabDropDown '; import LoadingSpinner from '@/components/LoadingSpinner'; +import Refresh from '@/components/Refresh'; export default function MyWineListContainer({ setDataCount }: { setDataCount: (value: number) => void }) { const [myWineData, setMyWineData] = useState([]); const [isLoading, setIsloading] = useState(true); + const [error, setError] = useState(''); const getMyWine = useCallback(async () => { + setError(''); try { setIsloading(true); const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/users/me/wines?limit=30`); if (!response?.ok || response === null) { + setError('와인 데이터를 불러오는데 실패했습니다.'); return; } @@ -26,7 +30,11 @@ export default function MyWineListContainer({ setDataCount }: { setDataCount: (v setMyWineData(data.list); setDataCount(data.totalCount); } catch (error) { - console.error('와인을 불러오는 중 문제가 발생했습니다:', error); + if (error instanceof Error) { + setError(error.message); + } else { + setError('알 수 없는 오류가 발생했습니다.'); + } } finally { setIsloading(false); } @@ -53,6 +61,17 @@ export default function MyWineListContainer({ setDataCount }: { setDataCount: (v if (isLoading) return ; + if (error) + return ( + + ); + if (myWineData.length === 0) return (
diff --git a/src/components/Refresh.tsx b/src/components/Refresh.tsx new file mode 100644 index 0000000..57c4800 --- /dev/null +++ b/src/components/Refresh.tsx @@ -0,0 +1,30 @@ +import Image from 'next/image'; +import emptyData from '@/assets/icons/empty_review.svg'; +import Button from '@/components/Button'; + +interface RefreshProps { + handleLoad: () => void; + boxStyle?: string; + iconSize?: string; + iconTextGap?: string; + buttonStyle?: string; +} + +export default function Refresh({ handleLoad, buttonStyle = 'px-[30px] py-[10px]', iconSize = 'h-[136px] w-[136px]', iconTextGap = 'gap-[10px]', boxStyle = 'gap-[10px]' }: RefreshProps) { + const onClickRefreshBtn = () => { + handleLoad(); + }; + + return ( +
+
+ 데이터 없음 +
+

서버에서 데이터를 불러오는 데

+

실패했습니다.

+
+
+
+ ); +}