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
6 changes: 6 additions & 0 deletions src/assets/icons/noWine.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions src/components/my-profile/Empty.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';

import Link from 'next/link';

import NoReviewIcon from '@/assets/icons/noReview.svg';
import NoWineIcon from '@/assets/icons/noWine.svg';
import { Button } from '@/components/ui/button';

interface MyPageEmptyProps {
type: 'reviews' | 'wines';
}

/**
* 내 프로필 페이지에서 데이터가 없을 때 표시되는 공통 Empty 컴포넌트
* - type: 'reviews' | 'wines' (내가 쓴 후기 / 내가 등록한 와인)
* - 리뷰는 '와인 보러가기' 링크
* - 와인은 와인 등록 버튼
*/
export default function MyPageEmpty({ type }: MyPageEmptyProps) {
const isReview = type === 'reviews';

return (
<div className='py-28 flex flex-col items-center justify-center gap-10 md:gap-12'>
<div className='w-[150px] h-[158px] text-gray-400'>
{isReview ? <NoReviewIcon /> : <NoWineIcon />}
</div>

<Button variant={'purpleDark'} className='w-[150px] h-[48px] md:w-[169px] '>
<Link href='/wines'>와인 보러가기</Link>
</Button>
</div>
);
}
23 changes: 13 additions & 10 deletions src/components/my-profile/ReviewList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { Badge } from '@/components/ui/badge';
import { useInfiniteScroll } from '@/hooks/useInfiniteScroll';
import { MyReview } from '@/types/MyReviewsTypes';

import MyPageEmpty from './Empty';

const PAGE_LIMIT = 10;

interface ReviewListProps {
Expand All @@ -30,13 +32,12 @@ export function ReviewList({ setTotalCount }: ReviewListProps) {
const observerRef = useRef<HTMLDivElement | null>(null);

// useInfiniteQuery 훅으로 리뷰 데이터를 무한 스크롤 형태로 조회
const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery({
queryKey: ['reviews'],
queryFn: ({ pageParam = 0 }) => getMyReviews({ cursor: pageParam, limit: PAGE_LIMIT }),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCursor ?? null,
});
const { data, isError, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({
queryKey: ['reviews'],
queryFn: ({ pageParam = 0 }) => getMyReviews({ cursor: pageParam, limit: PAGE_LIMIT }),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCursor ?? null,
});
// xhx
useEffect(() => {
if (data?.pages?.[0]?.totalCount != null) {
Expand All @@ -53,13 +54,15 @@ export function ReviewList({ setTotalCount }: ReviewListProps) {
});

// 로딩 및 에러 상태 처리 (임시)
if (isLoading) return <p>불러오는 중…</p>;
if (isError) return <p>불러오기 실패</p>;
if (!data) return <p>리뷰 데이터가 없습니다.</p>;

// 리뮤 목록 평탄화
// 리뷰 목록 평탄화
const reviews: MyReview[] = data?.pages?.flatMap((page) => page.list ?? []) ?? [];

if (!data || data.pages[0].list.length === 0) {
return <MyPageEmpty type='reviews' />;
}

return (
<div className='space-y-4 mt-4'>
{reviews.map((review) => (
Expand Down
19 changes: 11 additions & 8 deletions src/components/my-profile/WineList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import MenuDropdown from '@/components/common/dropdown/MenuDropdown';
import { Badge } from '@/components/ui/badge';
import { useInfiniteScroll } from '@/hooks/useInfiniteScroll';

import MyPageEmpty from './Empty';
import DeleteModal from '../Modal/DeleteModal/DeleteModal';
import EditWineModal from '../Modal/WineModal/EditWineModal';

Expand All @@ -31,13 +32,12 @@ export function WineList({ setTotalCount }: WineListProps) {
const [deleteWineId, setDeleteWineId] = useState<number | null>(null);

//useInfiniteQuery 훅으로 와인 데이터를 무한 스크롤 형태로 조회
const { data, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery({
queryKey: ['wines'],
queryFn: ({ pageParam = 0 }) => getMyWines({ cursor: pageParam, limit: PAGE_LIMIT }),
initialPageParam: 0,
getNextPageParam: (lastPage: MyWinesResponse | undefined) => lastPage?.nextCursor ?? null,
});
const { data, isError, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({
queryKey: ['wines'],
queryFn: ({ pageParam = 0 }) => getMyWines({ cursor: pageParam, limit: PAGE_LIMIT }),
initialPageParam: 0,
getNextPageParam: (lastPage: MyWinesResponse | undefined) => lastPage?.nextCursor ?? null,
});

useEffect(() => {
if (data?.pages?.[0]?.totalCount != null) {
Expand All @@ -54,12 +54,15 @@ export function WineList({ setTotalCount }: WineListProps) {
});

// 로딩 및 에러 상태 처리 (임시)
if (isLoading) return <p className='text-center py-4'>와인 불러오는 중…</p>;
if (isError || !data) return <p className='text-center py-4'>와인 불러오기 실패</p>;

// 와인 목록 평탄화
const wines: MyWine[] = data?.pages?.flatMap((page) => page?.list ?? []) ?? [];

if (!data || data.pages[0].list.length === 0) {
return <MyPageEmpty type='wines' />;
}

return (
<div className='flex flex-col mt-9 space-y-9 md:space-y-16 md:mt-16'>
{wines.map((wine) => (
Expand Down
2 changes: 1 addition & 1 deletion src/pages/my-profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function MyProfile() {
const [winesCount, setWinesCount] = useState(0);

return (
<div className='min-h-screen'>
<div>
<main className='max-w-6xl mx-auto p-4 gap-6 flex flex-col xl:flex-row'>
{/* 프로필 섹션 */}
<Profile />
Expand Down