Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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' className='mt-20' />;
}

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' className='mt-20' />;
}

return (
<div className='flex flex-col mt-9 space-y-9 md:space-y-16 md:mt-16'>
{wines.map((wine) => (
Expand Down
Loading