diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts
index cda8b28b..accc7011 100644
--- a/src/@types/trips.types.ts
+++ b/src/@types/trips.types.ts
@@ -6,3 +6,13 @@ interface TripRequest {
area: string;
subarea: string;
}
+
+interface MyTripType {
+ tripId: number;
+ tripName: string;
+ startDate: string;
+ endDate: string;
+ numberOfTripMembers: number;
+ tripStatus: string;
+ tripThumbnailUrl: string;
+}
diff --git a/src/api/member.ts b/src/api/member.ts
index 1e355324..0a5e6093 100644
--- a/src/api/member.ts
+++ b/src/api/member.ts
@@ -44,9 +44,13 @@ export const deleteMember = async () => {
};
// 나의 여정 조회
-export const getMemberTrips = async () => {
- const res = await authClient.get(`member/trips`);
- return res;
+export const getMemberTrips = async (page?: number, size?: number) => {
+ try {
+ const res = await authClient.get(`trips?&page=${page}&size=${size}`);
+ return res.data;
+ } catch (e) {
+ console.error(e);
+ }
};
// 나의 관심 여행지 조회
diff --git a/src/components/MyTrip/CreateMyTripButton.tsx b/src/components/MyTrip/CreateMyTripButton.tsx
new file mode 100644
index 00000000..347d70ed
--- /dev/null
+++ b/src/components/MyTrip/CreateMyTripButton.tsx
@@ -0,0 +1,9 @@
+const CreateMyTripButton = () => {
+ return (
+
+
+
+ );
+};
+
+export default CreateMyTripButton;
diff --git a/src/components/MyTrip/MyTrip.tsx b/src/components/MyTrip/MyTrip.tsx
new file mode 100644
index 00000000..3d7a7813
--- /dev/null
+++ b/src/components/MyTrip/MyTrip.tsx
@@ -0,0 +1,59 @@
+import { useInfiniteQuery } from '@tanstack/react-query';
+import MyTripList from './MyTripList';
+import NoDataMessage from '@components/common/noData/NoDataMessage';
+import { getMemberTrips } from '@api/member';
+import { PenIcon } from '@components/common/icons/Icons';
+
+const MyTrip = () => {
+ const { fetchNextPage, hasNextPage, data, isLoading, error } =
+ useInfiniteQuery({
+ queryKey: ['wishList'],
+ queryFn: ({ pageParam = 0 }) => getMemberTrips(pageParam, 10),
+ initialPageParam: 0,
+ getNextPageParam: (lastPage) => {
+ if (
+ lastPage &&
+ lastPage.data &&
+ lastPage.data &&
+ lastPage.data.pageable
+ ) {
+ const currentPage = lastPage.data.pageable.pageNumber;
+ const totalPages = lastPage.data.totalPages;
+
+ if (currentPage < totalPages - 1) {
+ return currentPage + 1;
+ }
+ }
+ return undefined;
+ },
+ });
+
+ if (error) {
+ return 데이터를 불러오는 중 오류가 발생했습니다.
;
+ }
+
+ return (
+
+
+
나의 여정
+
+
+ {data?.pages[0].data.content.length > 0 ? (
+
+ ) : (
+
}
+ />
+ )}
+
+ );
+};
+
+export default MyTrip;
diff --git a/src/components/MyTrip/MyTripItem.tsx b/src/components/MyTrip/MyTripItem.tsx
new file mode 100644
index 00000000..aff1a8da
--- /dev/null
+++ b/src/components/MyTrip/MyTripItem.tsx
@@ -0,0 +1,72 @@
+import { MoreIcon } from '@components/common/icons/Icons';
+
+interface MyTripItemProps {
+ myTripList: MyTripType;
+}
+
+const MyTripItem: React.FC = ({ myTripList }) => {
+ const {
+ tripName,
+ startDate,
+ endDate,
+ numberOfTripMembers,
+ tripStatus,
+ tripThumbnailUrl,
+ } = myTripList;
+
+ const ACTIVE_TRIP = '여행 중';
+ const COMPLETED_TRIP = '여행 후';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {tripStatus}
+
+
+
+ {tripName}
+
+
+ {startDate} ~ {endDate}
+
+
+
+ {numberOfTripMembers}명과 공유중
+
+
+
+
+
+
+ );
+};
+
+export default MyTripItem;
diff --git a/src/components/MyTrip/MyTripList.tsx b/src/components/MyTrip/MyTripList.tsx
new file mode 100644
index 00000000..bfb6ca22
--- /dev/null
+++ b/src/components/MyTrip/MyTripList.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import InfiniteScroll from 'react-infinite-scroller';
+import { v4 as uuidv4 } from 'uuid';
+import ToursItemSkeleton from '@components/Tours/ToursItemSkeleton';
+import MyTripItem from './MyTripItem';
+
+interface MyTripListProps {
+ myTripsData: { pages: Array<{ data: { content: MyTripType[] } }> };
+ fetchNextPage: () => void;
+ hasNextPage: boolean;
+ isLoading: boolean;
+}
+
+const MyTripList: React.FC = ({
+ myTripsData,
+ fetchNextPage,
+ hasNextPage,
+ isLoading,
+}) => {
+ if (!myTripsData || myTripsData.pages.length === 0) {
+ return 데이터를 불러오는 중 오류가 발생했습니다.
;
+ }
+
+ return (
+ fetchNextPage()}
+ hasMore={hasNextPage}
+ loader={
+
+ }>
+
+ {isLoading
+ ? Array.from({ length: 10 }, (_, index) => (
+
+ ))
+ : myTripsData.pages.map((group) => (
+
+ {group?.data.content.map((myTripList: MyTripType) => (
+
+ ))}
+
+ ))}
+
+
+ );
+};
+
+export default MyTripList;
diff --git a/src/components/Mypage/MypageList.tsx b/src/components/Mypage/MypageList.tsx
index 266dad60..ed6dbbae 100644
--- a/src/components/Mypage/MypageList.tsx
+++ b/src/components/Mypage/MypageList.tsx
@@ -3,7 +3,7 @@ import MypageItem from './MypageItem';
const MypageList = () => {
return (
- 나의 여정
+ 나의 여정
나의 관심 여행지
나의 리뷰
나의 여행 취향 설정
diff --git a/src/components/Wish/Wish.tsx b/src/components/Wish/Wish.tsx
index af2d8acb..6a0e219a 100644
--- a/src/components/Wish/Wish.tsx
+++ b/src/components/Wish/Wish.tsx
@@ -1,9 +1,9 @@
import { useState } from 'react';
import { useInfiniteQuery } from '@tanstack/react-query';
-import { getMemberTours } from '@api/member';
import WishCategory from './WishCategory';
import WishList from './WishList';
import NoDataMessage from '@components/common/noData/NoDataMessage';
+import { getMemberTours } from '@api/member';
import { HeartIcon } from '@components/common/icons/Icons';
const Wish = () => {
diff --git a/src/components/Wish/WishItem.tsx b/src/components/Wish/WishItem.tsx
index e0cfb679..6b30c0b5 100644
--- a/src/components/Wish/WishItem.tsx
+++ b/src/components/Wish/WishItem.tsx
@@ -57,7 +57,7 @@ const WishItem: React.FC = ({ wishList }) => {
{(Math.ceil(ratingAverage * 100) / 100).toFixed(1)}
- ({reviewCount.toLocaleString()})
+ ({reviewCount ? reviewCount.toLocaleString() : reviewCount})
@@ -66,7 +66,7 @@ const WishItem: React.FC = ({ wishList }) => {
- {likedCount.toLocaleString()}
+ {likedCount ? likedCount.toLocaleString() : likedCount}
diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx
index 3c28aa46..ca6db260 100644
--- a/src/components/common/icons/Icons.tsx
+++ b/src/components/common/icons/Icons.tsx
@@ -119,6 +119,80 @@ export const CalendarIcon: React.FC = ({
);
};
+export const CalendarIcon2: React.FC = ({ size = 25 }) => {
+ return (
+
+ );
+};
+
export const HeartIcon: React.FC = ({
size = 25,
color = 'black',
diff --git a/src/components/common/nav/Nav.tsx b/src/components/common/nav/Nav.tsx
index e99f5789..5fb9d35a 100644
--- a/src/components/common/nav/Nav.tsx
+++ b/src/components/common/nav/Nav.tsx
@@ -1,5 +1,11 @@
import { useLocation, useNavigate } from 'react-router-dom';
-import { CalendarIcon, HeartIcon, HomeIcon, UserIcon } from '../icons/Icons';
+import {
+ CalendarIcon,
+ CalendarIcon2,
+ HeartIcon,
+ HomeIcon,
+ UserIcon,
+} from '../icons/Icons';
import { useEffect, useState } from 'react';
import Alert from '../alert/Alert';
@@ -38,12 +44,37 @@ const Nav = () => {
홈
- navigate('/')}
- className="cursor-pointer flex-col items-center justify-center px-2">
-
-
일정
-
+
+ {isLoggedIn ? (
+ navigate('/mytrip')}
+ className="cursor-pointer flex-col items-center justify-center px-2">
+
+ {isActive('/mytrip') ? : }
+
+
여정
+
+ ) : (
+
+ 나의 여정 조회를 위해 로그인이 필요합니다.
+
+ 로그인 하시겠습니까?
+ >
+ }
+ onConfirm={handleConfirm}>
+
+
+ )}
{isLoggedIn ? (
{
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default MyTripPage;
diff --git a/src/router/mainRouter.tsx b/src/router/mainRouter.tsx
index c91a2dce..1cbe518c 100644
--- a/src/router/mainRouter.tsx
+++ b/src/router/mainRouter.tsx
@@ -5,6 +5,7 @@ import Detail from '@pages/detail/detail.page';
import ReviewComment from '@pages/reviewComment/reviewComment.page';
import ReviewPosting from '@pages/reviewPosting/reviewPosting.page';
import WishList from '@pages/wishList/wishList.page';
+import MyTripPage from '@pages/myTrip/myTrip.page';
import MyPageReview from '@pages/myPageReview/myPageReview.page';
import { Signup, SignupSuccess, SignupSurvey, SignupInfo } from '@pages/signup';
import { Login, LoginKakao } from '@pages/login';
@@ -31,6 +32,7 @@ const MainRouter = () => {
} />
} />
} />
+ } />
} />
} />
} />