From 0b312885a0723d80d73ff9da2397678089a17913 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Thu, 18 Jan 2024 05:54:03 +0900 Subject: [PATCH 01/62] =?UTF-8?q?Design:=20=EA=B3=B5=EC=9C=A0=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 35 ++++++++++++++++ src/api/trips.ts | 12 ++++++ src/components/Share/CopyBox.tsx | 38 +++++++++++++++++ src/components/Share/CopyToast.tsx | 36 ++++++++++++++++ src/components/Trip/TripSectionTop.tsx | 5 ++- src/components/common/BackBox/BackBox.tsx | 6 ++- src/pages/share/share.page.tsx | 51 +++++++++++++++++++++++ src/router/socketRouter.tsx | 2 + tailwind.config.js | 2 + 10 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 src/components/Share/CopyBox.tsx create mode 100644 src/components/Share/CopyToast.tsx create mode 100644 src/pages/share/share.page.tsx diff --git a/package.json b/package.json index 753474f8..a47d801e 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-toggle-group": "^1.0.4", "@stomp/stompjs": "^7.0.0", "@svgr/rollup": "^8.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d42035a..ed96f9f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ dependencies: '@radix-ui/react-tabs': specifier: ^1.0.4 version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toast': + specifier: ^1.1.5 + version: 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toggle-group': specifier: ^1.0.4 version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) @@ -2424,6 +2427,38 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-toast@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.45)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.45 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-toggle-group@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==} peerDependencies: diff --git a/src/api/trips.ts b/src/api/trips.ts index 3441cb6b..e704e469 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -68,3 +68,15 @@ export const getTripsSurvey = async (tripId: number) => { const res = await client.get(`trips/${tripId}/survey`); return res; }; + +// 여정 참여 코드 조회 +export const getTripsjoin = async (tripId: number) => { + const res = await authClient.get(`trips/${tripId}/join`); + return res; +}; + +// 여정 참여 +export const postTripsjoin = async (tripId: number, joinCode: number) => { + const res = await client.post(`trips/${tripId}/join`, { joinCode }); + return res; +}; diff --git a/src/components/Share/CopyBox.tsx b/src/components/Share/CopyBox.tsx new file mode 100644 index 00000000..7dc6a289 --- /dev/null +++ b/src/components/Share/CopyBox.tsx @@ -0,0 +1,38 @@ +import CopyToast from './CopyToast'; + +interface Props { + title: string; + subTitle: string; + copyValue: string; +} + +const CopyBox = ({ title, subTitle, copyValue }: Props) => { + const onCopyClick = () => { + navigator.clipboard.writeText(copyValue); + }; + + return ( +
+
+ {`${title} 복사`} + {subTitle} +
+
+ + +
+ 복사 +
+
+
+
+ ); +}; + +export default CopyBox; diff --git a/src/components/Share/CopyToast.tsx b/src/components/Share/CopyToast.tsx new file mode 100644 index 00000000..4f7492a3 --- /dev/null +++ b/src/components/Share/CopyToast.tsx @@ -0,0 +1,36 @@ +import * as Toast from '@radix-ui/react-toast'; +import { ReactNode, useState } from 'react'; +import { ReactComponent as CircleCheckIcon } from '@assets/images/CircleCheck.svg'; + +interface Props { + title: string; + children: ReactNode; +} + +const CopyToast = ({ title, children }: Props) => { + const [open, setOpen] = useState(false); + + return ( + + + + + + + {`${title}가 복사되었습니다.`} + + + + + ); +}; + +export default CopyToast; diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index 82e03c8e..de28b0a6 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -13,10 +13,13 @@ const TripSectionTop = () => {
{ navigate(-1); }} + showShare={true} + shareHandler={() => { + navigate('share'); + }} /> diff --git a/src/components/common/BackBox/BackBox.tsx b/src/components/common/BackBox/BackBox.tsx index 4af0db0f..0d29c96f 100644 --- a/src/components/common/BackBox/BackBox.tsx +++ b/src/components/common/BackBox/BackBox.tsx @@ -10,6 +10,7 @@ interface Props { showSave?: boolean; saveHandler?: VoidFunction; showShare?: boolean; + shareHandler?: VoidFunction; } const BackBox = ({ @@ -21,6 +22,7 @@ const BackBox = ({ showSave, saveHandler, showShare, + shareHandler, }: Props) => { const onBackClick = () => { backHandler && backHandler(); @@ -55,7 +57,9 @@ const BackBox = ({ )} {showShare && ( - )} diff --git a/src/pages/share/share.page.tsx b/src/pages/share/share.page.tsx new file mode 100644 index 00000000..afa87318 --- /dev/null +++ b/src/pages/share/share.page.tsx @@ -0,0 +1,51 @@ +import { getTripsjoin } from '@api/trips'; +import CopyBox from '@components/Share/CopyBox'; +import { BackBox } from '@components/common'; +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +const Share = () => { + const navigate = useNavigate(); + const [joinCode, setJoinCode] = useState(null); + + useEffect(() => { + const getTripCode = async () => { + try { + const { data } = await getTripsjoin(27); + if (data.status === 200) { + setJoinCode(data.data); + } + } catch (err) { + console.error(err); + } + }; + getTripCode(); + }, []); + return ( +
+ { + navigate(-1); + }}> + 공유하기 + +
+ + {joinCode && ( + + )} +
+
+ ); +}; + +export default Share; diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 4503f830..53fcb1ca 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -7,6 +7,7 @@ import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; import { useRecoilValue } from 'recoil'; import { tripIdState, visitDateState } from '@recoil/socket'; +import Share from '@pages/share/share.page'; const SocketRoutes = () => { const tripId = useRecoilValue(tripIdState); @@ -31,6 +32,7 @@ const SocketRouter = () => { }> } /> + } /> } /> diff --git a/tailwind.config.js b/tailwind.config.js index 0ec3313f..44bf1e11 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -6,6 +6,8 @@ export default { colors: { main1: '#062139', main2: '#29DDF6', + main3: '#DAF9FF', + main4: '#F2FDFF', sub1: '#FFEC3E', sub2: '#FF2167', gray1: '#f8f8f8', From d377689f99e698833c506d32d516078d9d435ee0 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Thu, 18 Jan 2024 07:34:13 +0900 Subject: [PATCH 02/62] =?UTF-8?q?Design:=20=EC=BD=94=EB=93=9C=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A7=88=ED=81=AC?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/trips.ts | 2 +- src/pages/share/shareCode.page.tsx | 82 ++++++++++++++++++++++++++++++ src/router/socketRouter.tsx | 2 + 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/pages/share/shareCode.page.tsx diff --git a/src/api/trips.ts b/src/api/trips.ts index e704e469..b2803936 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -76,7 +76,7 @@ export const getTripsjoin = async (tripId: number) => { }; // 여정 참여 -export const postTripsjoin = async (tripId: number, joinCode: number) => { +export const postTripsjoin = async (tripId: number, joinCode: string) => { const res = await client.post(`trips/${tripId}/join`, { joinCode }); return res; }; diff --git a/src/pages/share/shareCode.page.tsx b/src/pages/share/shareCode.page.tsx new file mode 100644 index 00000000..431f8e90 --- /dev/null +++ b/src/pages/share/shareCode.page.tsx @@ -0,0 +1,82 @@ +import { postTripsjoin } from '@api/trips'; +import { BackBox } from '@components/common'; +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +const shareCode = () => { + const navigate = useNavigate(); + const [inputCode, setInputCode] = useState(''); + const [showError, setShowError] = useState(false); + + const onCodeChange = async (e: React.ChangeEvent) => { + const changeValue = e.target.value; + if (changeValue.length <= 5) { + setInputCode(e.target.value); + } + if (changeValue.length === 5) { + try { + const res = await postTripsjoin(27, changeValue); + console.log(res); + } catch (err) { + setShowError(true); + setInputCode(''); + console.error('참여 코드 요청 중 에러 발생', err); + } + } + }; + + return ( +
+ { + navigate(-1); + }} + /> +
+
+ 편집 참여 코드 입력 + + 편집 참여 코드를 입력하면 여행 계획을 편집할 수 있어요. + +
+ +
+ + {inputCode.split('').map((code, index) => { + return ( +
+ {code} +
+ ); + })} + {Array(5 - inputCode.length) + .fill(null) + .map((_, index) => { + return ( +
+ ); + })} +
+ {showError && ( +
+ 편집 참여 코드를 다시 한번 확인해주세요. +
+ )} +
+
+ ); +}; + +export default shareCode; diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 53fcb1ca..111d60bd 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -8,6 +8,7 @@ import MainLayout from './routerLayout'; import { useRecoilValue } from 'recoil'; import { tripIdState, visitDateState } from '@recoil/socket'; import Share from '@pages/share/share.page'; +import ShareCode from '@pages/share/shareCode.page'; const SocketRoutes = () => { const tripId = useRecoilValue(tripIdState); @@ -33,6 +34,7 @@ const SocketRouter = () => { }> } /> } /> + } /> } /> From c458ba82477b0c625b788efcc92997c8fceb2bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Thu, 18 Jan 2024 12:53:14 +0900 Subject: [PATCH 03/62] =?UTF-8?q?Fix:=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/PlanTripButton.tsx | 12 ++++------ src/components/Trip/TripPreference.tsx | 4 +++- src/components/common/icons/Icons.tsx | 32 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/components/Trip/PlanTripButton.tsx b/src/components/Trip/PlanTripButton.tsx index bd5ac6fc..db7b4639 100644 --- a/src/components/Trip/PlanTripButton.tsx +++ b/src/components/Trip/PlanTripButton.tsx @@ -1,18 +1,16 @@ -import { PlanIcon, RightIcon } from '@components/common/icons/Icons'; +import { PlanColorIcon, RightIcon } from '@components/common/icons/Icons'; const PlanTripButton = () => { return ( - ); diff --git a/src/components/Trip/TripPreference.tsx b/src/components/Trip/TripPreference.tsx index 02f71976..368086d7 100644 --- a/src/components/Trip/TripPreference.tsx +++ b/src/components/Trip/TripPreference.tsx @@ -32,7 +32,9 @@ const TripPreferenceButton: React.FC = () => {
-

내 여행 취향 설정하러 가기

+

+ 내 여행 취향 설정하러 가기 +

diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 3d70d69e..bbd4e328 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1297,3 +1297,35 @@ export const CounterIcon: React.FC< ); }; + +export const PlanColorIcon: React.FC = ({ size = 21 }) => { + return ( + + + + + + + ); +}; From e1937df2fcdce8206a769635eb4099bd93a71a29 Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Thu, 18 Jan 2024 14:12:43 +0900 Subject: [PATCH 04/62] =?UTF-8?q?feat:=20=EC=B6=94=EA=B0=80,=20=EC=97=84?= =?UTF-8?q?=EC=A7=80=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/icons/Icons.tsx | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 493de888..ceca7ad9 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1308,3 +1308,90 @@ export const CounterIcon: React.FC< ); }; + +export const ThumbsUp: React.FC = ({ + size = 16, + fill = '#1E1E1E', +}) => { + return ( + + + + + + ); +}; + +export const ThumbsDown: React.FC = ({ + size = 16, + fill = '#1E1E1E', +}) => { + return ( + + + + + ); +}; + +export const NewIcon: React.FC = ({ + size = 11, + fill = '#1E1E1E', +}) => { + return ( + + + + + ); +}; From ee88bcf6e79b5821e3a70d4e37223a9dd6e8a2cd Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Thu, 18 Jan 2024 14:13:13 +0900 Subject: [PATCH 05/62] =?UTF-8?q?feat:=20=EC=9A=B0=EB=A6=AC=EC=9D=98=20?= =?UTF-8?q?=EA=B4=80=EC=8B=AC=EC=97=AC=ED=96=89=EC=A7=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/trips.types.ts | 21 +++ src/api/trips.ts | 13 +- src/components/Trip/LikedToursList.tsx | 86 +++++++++++- .../LikedToursLists/LikedToursListBox.tsx | 72 ++++++++++ .../LikedToursListCategory.tsx | 46 +++++++ .../LikedToursListCategoryItem.tsx | 29 ++++ .../LikedToursLists/LikedToursListItem.tsx | 129 ++++++++++++++++++ 7 files changed, 389 insertions(+), 7 deletions(-) create mode 100644 src/components/Trip/LikedToursLists/LikedToursListBox.tsx create mode 100644 src/components/Trip/LikedToursLists/LikedToursListCategory.tsx create mode 100644 src/components/Trip/LikedToursLists/LikedToursListCategoryItem.tsx create mode 100644 src/components/Trip/LikedToursLists/LikedToursListItem.tsx diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index fb708de8..4374a050 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -18,3 +18,24 @@ interface MyTripType { area: string; subArea: string; } + +interface ourTripType { + tripLikedItemId: number; + tourItemId: number; + contentTypeId: number; + ratingAverage: number; + reviewCount: number; + smallThumbnailUrl: string; + tourAddress: string; + prefer: boolean; + notPrefer: boolean; + preferTotalCount: number; + notPreferTotalCount: number; +} + +interface ThumbsProps { + tripId: number; + tourId: number; + prefer: boolean; + notPrefer: boolean; +} diff --git a/src/api/trips.ts b/src/api/trips.ts index 3441cb6b..1a395cf4 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -35,14 +35,14 @@ export const postTrips = async (tripsData: TripRequest) => { // 우리의 관심목록 조회 export const getTripsLike = async ( tripId: number, - category: number, page: number, size: number, ) => { - const res = await client.get( - `trips/${tripId}/tripLikedTours?category=${category}&page=${page}$size=${size}`, + const res = await authClient.get( + `trips/${tripId}/tripLikedTours?page=${page}&size=${size}`, ); - return res; + + return res.data; }; // 우리의 관심 목록 등록 @@ -56,9 +56,10 @@ export const postTripsLikeHate = async ( tripId: number, tourId: number, prefer: boolean, + notPrefer: boolean, ) => { - const res = await client.post( - `trips/${tripId}/tripLikedTours/${tourId}?prefer=${prefer}`, + const res = await authClient.post( + `trips/${tripId}/tripLikedTours/${tourId}?prefer=${prefer}¬Prefer=${notPrefer}`, ); return res; }; diff --git a/src/components/Trip/LikedToursList.tsx b/src/components/Trip/LikedToursList.tsx index 67119420..de2a69e9 100644 --- a/src/components/Trip/LikedToursList.tsx +++ b/src/components/Trip/LikedToursList.tsx @@ -1,3 +1,87 @@ +import { useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { useInfiniteQuery } from '@tanstack/react-query'; + +import LikedToursListCategory from './LikedToursLists/LikedToursListCategory'; +import LikedToursListBox from './LikedToursLists/LikedToursListBox'; +import NoDataMessage from '@components/common/noData/NoDataMessage'; + +import { getTripsLike } from '@api/trips'; +import { HeartIcon, NewIcon } from '@components/common/icons/Icons'; + export const LikedToursList = () => { - return
LikedToursList
; + const [selectedContentTypeId, setSelectedContentTypeId] = useState< + null | number + >(null); + const params = useParams(); + const [selectedTripId, _] = useState(Number(params.id)); + + const { fetchNextPage, hasNextPage, data, isLoading, error } = + useInfiniteQuery({ + queryKey: ['ourTrips'], + queryFn: ({ pageParam = 0 }) => + getTripsLike(selectedTripId, 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; + }, + }); + + const handleCategoryClick = (contentTypeId: number | null) => { + setSelectedContentTypeId(contentTypeId); + }; + + if (error) { + return
데이터를 불러오는 중 오류가 발생했습니다.
; + } + + return ( +
+ + + {data?.pages[0].data.content.length > 0 ? ( +
+ +
+ ) : ( +
+ } + /> +
+ )} + + {/* 검색 라우터 이동 */} +
+ +
+
+ ); }; diff --git a/src/components/Trip/LikedToursLists/LikedToursListBox.tsx b/src/components/Trip/LikedToursLists/LikedToursListBox.tsx new file mode 100644 index 00000000..56c2db3d --- /dev/null +++ b/src/components/Trip/LikedToursLists/LikedToursListBox.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import InfiniteScroll from 'react-infinite-scroller'; +import { v4 as uuidv4 } from 'uuid'; +import ToursItemSkeleton from '@components/Tours/ToursItemSkeleton'; +// import { Spinner } from '@components/common/spinner/Spinner'; + +import LikedToursListItem from './LikedToursListItem'; + +interface LikedToursListProps { + toursData: { pages: Array<{ data: { content: ourTripType[] } }> }; + fetchNextPage: () => void; + hasNextPage: boolean; + isLoading: boolean; + selectedContentTypeId: number | null; + selectedTripId: number; +} + +const LikedToursListBox: React.FC = ({ + toursData, + fetchNextPage, + hasNextPage, + isLoading, + selectedContentTypeId, + selectedTripId, +}) => { + if (!toursData || toursData.pages.length === 0) { + return
데이터를 불러오는 중 오류가 발생했습니다.
; + } + + const filteredData = + selectedContentTypeId !== null + ? toursData.pages.map((group) => ({ + data: { + content: group.data.content.filter( + (item) => item.contentTypeId === selectedContentTypeId, + ), + }, + })) + : toursData.pages; + + return ( + fetchNextPage()} + hasMore={hasNextPage} + loader={ +
+ {/* */} +
+ }> +
+ {isLoading + ? Array.from({ length: 10 }, (_, index) => ( + + )) + : filteredData.map((group) => ( + + {group?.data.content.map((ourTripList: ourTripType) => ( + + ))} + + ))} +
+
+ ); +}; + +export default LikedToursListBox; diff --git a/src/components/Trip/LikedToursLists/LikedToursListCategory.tsx b/src/components/Trip/LikedToursLists/LikedToursListCategory.tsx new file mode 100644 index 00000000..8a243c2f --- /dev/null +++ b/src/components/Trip/LikedToursLists/LikedToursListCategory.tsx @@ -0,0 +1,46 @@ +import { useState } from 'react'; +import { LikedToursListCategoryItem } from './LikedToursListCategoryItem'; + +interface LikedToursListCategoryProps { + onCategoryClick: (contentTypeId: number | null) => void; +} + +const LikedToursListCategory: React.FC = ({ + onCategoryClick, +}) => { + const [selectedCategory, setSelectedCategory] = useState('전체'); + + const categories = [ + { code: null, name: '전체' }, + { code: 12, name: '관광지' }, + { code: 32, name: '숙소' }, + { code: 39, name: '식당' }, + ]; + + const handleSelectCategory = (name: string) => { + setSelectedCategory(name); + window.scrollTo({ + top: 0, + left: 0, + behavior: 'smooth', + }); + }; + + return ( +
+ {categories.map((category) => { + return ( + + ); + })} +
+ ); +}; + +export default LikedToursListCategory; diff --git a/src/components/Trip/LikedToursLists/LikedToursListCategoryItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListCategoryItem.tsx new file mode 100644 index 00000000..d795f8f0 --- /dev/null +++ b/src/components/Trip/LikedToursLists/LikedToursListCategoryItem.tsx @@ -0,0 +1,29 @@ +interface LikedToursListCategoryItemProps { + category: { code: number | null; name: string }; + onCategoryClick: (contentTypeId: number | null) => void; + onSelect: (name: string) => void; + isSelected: boolean; +} + +export const LikedToursListCategoryItem: React.FC< + LikedToursListCategoryItemProps +> = ({ category, onCategoryClick, onSelect, isSelected }) => { + const handleCategoryClick = () => { + if (category.code !== undefined) { + onCategoryClick(category.code); + onSelect(category.name); + } + }; + + const buttonStyle = isSelected + ? 'bg-[#28D8FF] text-white font-bold' + : 'bg-[#fff] text-[#888] border-[#ededed]'; + + return ( + + ); +}; diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx new file mode 100644 index 00000000..4577f448 --- /dev/null +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -0,0 +1,129 @@ +import { ThumbsUp, ThumbsDown, StarIcon } from '@components/common/icons/Icons'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { postTripsLikeHate } from '@api/trips'; +import { useNavigate } from 'react-router-dom'; +import { useState } from 'react'; + +interface LikedToursListItemProps { + ourTripList: ourTripType; + selectedTripId: number; +} + +const LikedToursListItem: React.FC = ({ + ourTripList, + selectedTripId, +}) => { + const { + tourItemId, + ratingAverage, + reviewCount, + prefer, + notPrefer, + preferTotalCount, + notPreferTotalCount, + smallThumbnailUrl, + tourAddress, + } = ourTripList; + const navigate = useNavigate(); + const queryClient = useQueryClient(); + const [thumbsState, setThumbsState] = useState({ + prefer: false, + notPrefer: false, + }); + + const { mutate: thumbsUpMutate } = useMutation({ + mutationFn: () => + postTripsLikeHate( + selectedTripId, + tourItemId, + thumbsState.prefer, + thumbsState.notPrefer, + ), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['ourTrips'] }); + }, + onError: () => console.log('error'), + }); + + const onClickThumbsUpButton = (e: React.MouseEvent) => { + e.stopPropagation(); + setThumbsState({ prefer: true, notPrefer: false }); + thumbsUpMutate(); + }; + + const onClickThumbsDownButton = (e: React.MouseEvent) => { + e.stopPropagation(); + setThumbsState({ prefer: false, notPrefer: true }); + thumbsUpMutate(); + }; + + return ( +
navigate(`/detail/${tourItemId}`)}> +
+
+ 여행지 이미지 +
+ +
+
+

+ 타이틀 +

+ +
+
+
+ +
+ +
+ + {(Math.ceil(ratingAverage * 100) / 100).toFixed(1)} + + + ({reviewCount ? reviewCount.toLocaleString() : reviewCount}) + +
+
+ +
+

+ {tourAddress ? tourAddress : '주소를 제공하지 않고 있어요'} +

+
+
+
+ +
+
+ + +
+
+
+
+
+ ); +}; + +export default LikedToursListItem; From 468b1b812a4171ce4b174775e0de65f62ee58022 Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Thu, 18 Jan 2024 14:21:39 +0900 Subject: [PATCH 06/62] =?UTF-8?q?style:=20truncate=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Trip/LikedToursLists/LikedToursListItem.tsx | 4 ++-- src/components/Wish/WishItem.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index 4577f448..765ded43 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -92,8 +92,8 @@ const LikedToursListItem: React.FC = ({
-
-

+

+

{tourAddress ? tourAddress : '주소를 제공하지 않고 있어요'}

diff --git a/src/components/Wish/WishItem.tsx b/src/components/Wish/WishItem.tsx index 6b30c0b5..e8c12eb9 100644 --- a/src/components/Wish/WishItem.tsx +++ b/src/components/Wish/WishItem.tsx @@ -38,12 +38,12 @@ const WishItem: React.FC = ({ wishList }) => {
-
-

+

+

{title}

-
-

{tourAddress}

+
+

{tourAddress}

From 5083a61582f7df92ef6e02ebc4d3cee680a4b68b Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Thu, 18 Jan 2024 14:29:24 +0900 Subject: [PATCH 07/62] =?UTF-8?q?feat:=20=EC=B6=94=EA=B0=80=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/LikedToursList.tsx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/Trip/LikedToursList.tsx b/src/components/Trip/LikedToursList.tsx index de2a69e9..b11271da 100644 --- a/src/components/Trip/LikedToursList.tsx +++ b/src/components/Trip/LikedToursList.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { useInfiniteQuery } from '@tanstack/react-query'; import LikedToursListCategory from './LikedToursLists/LikedToursListCategory'; @@ -13,7 +13,10 @@ export const LikedToursList = () => { const [selectedContentTypeId, setSelectedContentTypeId] = useState< null | number >(null); + + const navigate = useNavigate(); const params = useParams(); + const [selectedTripId, _] = useState(Number(params.id)); const { fetchNextPage, hasNextPage, data, isLoading, error } = @@ -40,14 +43,14 @@ export const LikedToursList = () => { }, }); - const handleCategoryClick = (contentTypeId: number | null) => { - setSelectedContentTypeId(contentTypeId); - }; - if (error) { return
데이터를 불러오는 중 오류가 발생했습니다.
; } + const handleCategoryClick = (contentTypeId: number | null) => { + setSelectedContentTypeId(contentTypeId); + }; + return (
@@ -73,9 +76,11 @@ export const LikedToursList = () => {
)} - {/* 검색 라우터 이동 */} + {/* 우리의 관심 여행지 추가 버튼 => 검색 라우터 이동 */}
-
); } diff --git a/src/components/DetailSectionTop/DetailToursRating.tsx b/src/components/DetailSectionTop/DetailToursRating.tsx index 0178f248..2be49e9c 100644 --- a/src/components/DetailSectionTop/DetailToursRating.tsx +++ b/src/components/DetailSectionTop/DetailToursRating.tsx @@ -1,5 +1,8 @@ import { useEffect, useState } from 'react'; import { Link } from 'react-scroll'; +import { useSetRecoilState } from 'recoil'; +import { reviewCountState } from '@recoil/review'; + interface ReviewData { ratingAverage: number; reviewTotalCount: number; @@ -13,6 +16,7 @@ export default function DetailToursRating({ reviewData, }: DetailToursRatingProps) { const { reviewTotalCount, ratingAverage } = reviewData; + const setReviewCount = useSetRecoilState(reviewCountState); const STAR_IDX_ARR = ['1', '2', '3', '4', '5']; const [ratedStarArr, setRatedStarArr] = useState([0, 0, 0, 0, 0]); @@ -32,6 +36,7 @@ export default function DetailToursRating({ useEffect(() => { setRatedStarArr(calculateRates(ratingAverage)); + setReviewCount(reviewTotalCount); }, []); return ( diff --git a/src/pages/detail/detail.page.tsx b/src/pages/detail/detail.page.tsx index bcccedb5..cee1949a 100644 --- a/src/pages/detail/detail.page.tsx +++ b/src/pages/detail/detail.page.tsx @@ -2,20 +2,15 @@ import { DetailHeader } from '@components/common/header'; import DetailSectionTop from '@components/DetailSectionTop/DetailSectionTop'; import DetailSectionBottom from '@components/DetailSectionBottom/DetailSectionBottom'; import { DetailTopButton } from '@components/DetailSectionTop'; -import { useRef } from 'react'; const DetailTours = () => { - const parentRef = useRef(null); - return ( -
+ <> -
- - -
-
+ + + ); }; diff --git a/src/recoil/review.ts b/src/recoil/review.ts index 6bb84cc2..1c9753e1 100644 --- a/src/recoil/review.ts +++ b/src/recoil/review.ts @@ -88,3 +88,8 @@ export const inputFocusState = atom({ key: 'inputFocusState', default: false, }); + +export const reviewCountState = atom({ + key: 'reviewCountState', + default: 0, +}); From 8d6e4e29eb24c199f4e940eb98c5973f9472da76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Thu, 18 Jan 2024 16:22:27 +0900 Subject: [PATCH 09/62] =?UTF-8?q?Feat:=20=EC=A0=91=EC=86=8D=EC=A4=91=20?= =?UTF-8?q?=EA=B3=B5=EC=9C=A0=EB=A9=A4=EB=B2=84=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/service.ts | 6 +- src/@types/socket.types.ts | 6 +- src/components/Plan/PlanSectionTop.tsx | 8 ++- src/components/Trip/TripInfo.tsx | 17 +----- src/components/Trip/TripRealtimeEditor.tsx | 66 ++++++++++++++++++++++ src/components/Trip/TripSchedule.tsx | 22 ++++++++ 6 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 src/components/Trip/TripRealtimeEditor.tsx create mode 100644 src/components/Trip/TripSchedule.tsx diff --git a/src/@types/service.ts b/src/@types/service.ts index 8706a8da..26d684d6 100644 --- a/src/@types/service.ts +++ b/src/@types/service.ts @@ -78,15 +78,11 @@ export type subMemberRes = { message: string; data: { tripId: number; - connectedMembers: { - memberId: number; - name: string; - thumbnailUrl: string; - }[]; tripMembers: { memberId: number; name: string; thumbnailUrl: string; + connected: boolean; }[]; numberOfPeople: number; } | null; diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index be9c82fa..128a9d20 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -62,15 +62,11 @@ type subMemberMessage = (response: { message: string; data: { tripId: number; - connectedMembers: { - memberId: number; - name: string; - thumbnailUrl: string; - }[]; tripMembers: { memberId: number; name: string; thumbnailUrl: string; + connected: boolean; }[]; numberOfPeople: number; }; diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 37224884..9d24dd6f 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -1,4 +1,4 @@ -import TripInfo from '@components/Trip/TripInfo'; +import TripRealtimeEditor from '@components/Trip/TripRealtimeEditor'; import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import TripBudget from './TripBudget'; @@ -11,6 +11,7 @@ import { useEffect } from 'react'; import { useRecoilValue } from 'recoil'; import { tripIdState, memberIdState } from '@recoil/socket'; import { calculateDayAndDate } from '@utils/utils'; +import { TripSchedule } from '@components/Trip/TripSchedule'; const PlanSectionTop = () => { const navigate = useNavigate(); @@ -36,7 +37,7 @@ const PlanSectionTop = () => { if (startDate && endDate) { ({ DayArr, DateArr } = calculateDayAndDate(startDate, endDate)); } - + return (
{ navigate(-1); }} /> - + + {
{isAccordion && } -
-
-
-
강릉 여행 일정
-
- - 5 -
-
- -
- 23.12.23 - 23.12.25 +
{modalChildren === 'TripSurveyMember' && } diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx new file mode 100644 index 00000000..2e5428ca --- /dev/null +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -0,0 +1,66 @@ +import { useRecoilValue } from 'recoil'; +import { tripIdState, memberIdState } from '@recoil/socket'; +import { useEffect } from 'react'; +import { socketContext } from '@hooks/useSocket'; +import { useContext } from 'react'; +import { pubConnectMember, pubDisconnectMember } from '@api/socket'; +import { UserIcon } from '@components/common/icons/Icons'; + +const TripRealtimeEditor = () => { + const tripId = useRecoilValue(tripIdState); + const pubMember = useRecoilValue(memberIdState); + if (!pubMember || !tripId) { + return
에러
; + } + + const { callBackPub, tripMember } = useContext(socketContext); + + useEffect(() => { + callBackPub(() => pubConnectMember(pubMember, tripId)); + return () => { + callBackPub(() => pubDisconnectMember(pubMember, tripId)); + }; + }, []); + + const tripMemberData = tripMember?.data; + + return ( +
+ {tripMemberData?.tripMembers?.map((member) => { + const isConnected = member?.connected; + const thumbnailUrl = member?.thumbnailUrl; + const isImageUrlValid = + thumbnailUrl && thumbnailUrl !== 'http://asiduheimage.jpg'; + const imageUrl = isImageUrlValid ? thumbnailUrl : null; + + return ( +
+ {imageUrl ? ( + 유저 프로필 + ) : ( +
+ +
+ )} +
+ + {member?.name} + +
+
+ ); + })} +
+ ); +}; + +export default TripRealtimeEditor; diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx new file mode 100644 index 00000000..efca618b --- /dev/null +++ b/src/components/Trip/TripSchedule.tsx @@ -0,0 +1,22 @@ +import { UserIcon } from '@components/common/icons/Icons'; + +export const TripSchedule = () => { + return ( + <> +
+
+
+
강릉 여행 일정
+
+ + 5 +
+
+ +
+ 23.12.23 - 23.12.25 + + ); +}; From 273f84251b7024fa0c042620d3bc53f20afd4c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Thu, 18 Jan 2024 16:33:44 +0900 Subject: [PATCH 10/62] =?UTF-8?q?Fix:=20alert=20=EC=B0=BD=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripSchedule.tsx | 3 ++- src/components/common/modal/Modal.tsx | 10 +++++----- src/components/common/modal/children/MyAlert.tsx | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index efca618b..878d730a 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -1,9 +1,10 @@ import { UserIcon } from '@components/common/icons/Icons'; +import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; export const TripSchedule = () => { return ( <> -
+
강릉 여행 일정
diff --git a/src/components/common/modal/Modal.tsx b/src/components/common/modal/Modal.tsx index c8ec7ed8..bb558735 100644 --- a/src/components/common/modal/Modal.tsx +++ b/src/components/common/modal/Modal.tsx @@ -43,8 +43,8 @@ export const getModalStyles = (modalChildren: string) => { maxWidth: '412px', width: '100%', height: '186px', - borderTopLeftRadius: '2rem', - borderTopRightRadius: '2rem', + borderTopLeftRadius: '16px', + borderTopRightRadius: '16px', }, overlay: { backgroundColor: 'rgba(0, 0, 0, 0.25)', @@ -62,7 +62,7 @@ export const getModalStyles = (modalChildren: string) => { transform: 'translate(-50%, -50%)', width: '309px', height: '192px', - borderRadius: '2rem', + borderRadius: '16px', }, overlay: { backgroundColor: 'rgba(0, 0, 0, 0.25)', @@ -81,8 +81,8 @@ export const getModalStyles = (modalChildren: string) => { maxWidth: '412px', width: '100%', height: '280px', - borderTopLeftRadius: '2rem', - borderTopRightRadius: '2rem', + borderTopLeftRadius: '16px', + borderTopRightRadius: '16px', }, overlay: { backgroundColor: 'rgba(0, 0, 0, 0.25)', diff --git a/src/components/common/modal/children/MyAlert.tsx b/src/components/common/modal/children/MyAlert.tsx index e5f50f7e..7e226d68 100644 --- a/src/components/common/modal/children/MyAlert.tsx +++ b/src/components/common/modal/children/MyAlert.tsx @@ -69,7 +69,7 @@ const MyAlert: React.FC = ({ title, content }) => {
{title}
- {content.split('. ').map((sentence, index) => ( + {content.split(/(?<=\.) /).map((sentence, index) => (
{sentence}
From e82075bc56d195f22055f23f77ee7634a1b1511c Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Thu, 18 Jan 2024 17:36:55 +0900 Subject: [PATCH 11/62] =?UTF-8?q?refactor:=20API=20=EC=A0=9C=EB=AA=A9=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/trips.types.ts | 1 + src/components/Trip/LikedToursLists/LikedToursListItem.tsx | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index 4374a050..b265e709 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -31,6 +31,7 @@ interface ourTripType { notPrefer: boolean; preferTotalCount: number; notPreferTotalCount: number; + title: string; } interface ThumbsProps { diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index 765ded43..70d0c6f2 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -23,6 +23,7 @@ const LikedToursListItem: React.FC = ({ notPreferTotalCount, smallThumbnailUrl, tourAddress, + title, } = ourTripList; const navigate = useNavigate(); const queryClient = useQueryClient(); @@ -71,9 +72,9 @@ const LikedToursListItem: React.FC = ({
-
-

- 타이틀 +

+

+ {title}

From d335cda13fa3587d40ba8702ecc6f5e9556ceb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Thu, 18 Jan 2024 17:53:19 +0900 Subject: [PATCH 12/62] =?UTF-8?q?Fix:=20=EA=B8=B0=EB=B3=B8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripInfo.tsx | 19 ++++- src/components/Trip/TripParticipant.tsx | 11 ++- src/components/Trip/TripRealtimeEditor.tsx | 80 +++++++++++++--------- 3 files changed, 73 insertions(+), 37 deletions(-) diff --git a/src/components/Trip/TripInfo.tsx b/src/components/Trip/TripInfo.tsx index 306db026..b0f82678 100644 --- a/src/components/Trip/TripInfo.tsx +++ b/src/components/Trip/TripInfo.tsx @@ -6,9 +6,10 @@ import { Modal } from '@components/common/modal'; import { useQuery } from '@tanstack/react-query'; import { getTripsMembers } from '@api/trips'; import { tripIdState } from '@recoil/socket'; -import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; +// import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; import { DownIcon } from '@components/common/icons/Icons'; import { useState } from 'react'; +import { UserIcon } from '@components/common/icons/Icons'; const ShareList = () => { const tripId = Number(useRecoilValue(tripIdState)); @@ -35,7 +36,13 @@ const ShareList = () => { className="h-[32px] w-[32px] rounded-full" /> ) : ( - +
+ +
+ // )}
{member.nickname}
@@ -81,7 +88,13 @@ const TripInfo = () => { className="h-[32px] w-[32px] rounded-full border-2 border-solid border-white" /> ) : ( - +
+ +
+ // )}
))} diff --git a/src/components/Trip/TripParticipant.tsx b/src/components/Trip/TripParticipant.tsx index 934aa95e..f8fac765 100644 --- a/src/components/Trip/TripParticipant.tsx +++ b/src/components/Trip/TripParticipant.tsx @@ -1,6 +1,7 @@ -import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; +// import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; import { useRecoilValue } from 'recoil'; import { participantsState } from '@recoil/trip'; +import { UserIcon } from '@components/common/icons/Icons'; interface ParticipantStatusProps { status: string; @@ -19,7 +20,13 @@ const ParticipantList: React.FC<{ infos: any[] }> = ({ infos }) => ( className="h-[32px] w-[32px] rounded-full" /> ) : ( - +
+ +
+ // )}
{info.nickname}
diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index 2e5428ca..dc9a9232 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -5,6 +5,8 @@ import { socketContext } from '@hooks/useSocket'; import { useContext } from 'react'; import { pubConnectMember, pubDisconnectMember } from '@api/socket'; import { UserIcon } from '@components/common/icons/Icons'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import { Navigation } from 'swiper/modules'; const TripRealtimeEditor = () => { const tripId = useRecoilValue(tripIdState); @@ -25,40 +27,54 @@ const TripRealtimeEditor = () => { const tripMemberData = tripMember?.data; return ( -
- {tripMemberData?.tripMembers?.map((member) => { - const isConnected = member?.connected; - const thumbnailUrl = member?.thumbnailUrl; - const isImageUrlValid = - thumbnailUrl && thumbnailUrl !== 'http://asiduheimage.jpg'; - const imageUrl = isImageUrlValid ? thumbnailUrl : null; +
+ console.log('slide change')} + onSwiper={(swiper) => console.log(swiper)} + navigation={true} + modules={[Navigation]} + className="flex w-[375px] items-center justify-center"> + {tripMemberData?.tripMembers?.map((member) => { + const isConnected = member?.connected; + const thumbnailUrl = member?.thumbnailUrl; + const isImageUrlValid = + thumbnailUrl && thumbnailUrl !== 'http://asiduheimage.jpg'; + const imageUrl = isImageUrlValid ? thumbnailUrl : null; - return ( -
- {imageUrl ? ( - 유저 프로필 - ) : ( -
- + return ( + +
+ {imageUrl ? ( + 유저 프로필 + ) : ( +
+ +
+ )} +
+ + {member?.name} + +
- )} -
- - {member?.name} - -
-
- ); - })} + + ); + })} +
); }; From fda0ccb02693dc9b7e8748562b8556707968d427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Thu, 18 Jan 2024 18:25:44 +0900 Subject: [PATCH 13/62] =?UTF-8?q?Feat:=20swiper=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/socket.ts | 3 ++- src/components/Review/CommentItem.tsx | 6 +++--- src/components/Trip/TripRealtimeEditor.tsx | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/api/socket.ts b/src/api/socket.ts index 94033e68..6d70c14c 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -140,6 +140,7 @@ export const pubConnectMember = (pubMember: pubMember, tripId: string) => { destination: `/pub/trips/${tripId}/connectMember`, body: JSON.stringify(pubMember), }); + console.log('펍실행', pubMember); }; // 멤버 여정 페이지 퇴장 이벤트 발생시 @@ -163,7 +164,7 @@ export const pubGetPathAndItems = ( pubGetPathAndItems: pubGetPathAndItems, tripId: string, ) => { - console.log('펍내부',pubGetPathAndItems); + console.log('펍내부', pubGetPathAndItems); socketClient.publish({ destination: `/pub/trips/${tripId}/getPathAndItems`, body: JSON.stringify(pubGetPathAndItems), diff --git a/src/components/Review/CommentItem.tsx b/src/components/Review/CommentItem.tsx index c4e4d264..33712b0c 100644 --- a/src/components/Review/CommentItem.tsx +++ b/src/components/Review/CommentItem.tsx @@ -57,7 +57,7 @@ const CommentItem: React.FC = (props: ItemProps) => { return (
-
+
{!( authorProfileImageUrl === 'http://asiduheimage.jpg' || authorProfileImageUrl === null @@ -65,7 +65,7 @@ const CommentItem: React.FC = (props: ItemProps) => { 유저 프로필 ) : ( @@ -85,7 +85,7 @@ const CommentItem: React.FC = (props: ItemProps) => {
)}
-
{content}
+
{content}
); }; diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index dc9a9232..d151ed59 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -17,6 +17,7 @@ const TripRealtimeEditor = () => { const { callBackPub, tripMember } = useContext(socketContext); + console.log('pubMember', pubMember); useEffect(() => { callBackPub(() => pubConnectMember(pubMember, tripId)); return () => { @@ -27,7 +28,7 @@ const TripRealtimeEditor = () => { const tripMemberData = tripMember?.data; return ( -
+
console.log('slide change')} From 0f71e770d24310cd08852f01f275cc0d8c14cfd3 Mon Sep 17 00:00:00 2001 From: WookJin Date: Thu, 18 Jan 2024 18:39:00 +0900 Subject: [PATCH 14/62] Update DetailTopButton.tsx --- src/components/DetailSectionTop/DetailTopButton.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/DetailSectionTop/DetailTopButton.tsx b/src/components/DetailSectionTop/DetailTopButton.tsx index eb557523..2e5cd923 100644 --- a/src/components/DetailSectionTop/DetailTopButton.tsx +++ b/src/components/DetailSectionTop/DetailTopButton.tsx @@ -14,8 +14,9 @@ export default function DetailTopButton() { setVisible(false); } }, [getReviewCount]); - - const scrollToTop = () => { + + const scrollToTop = (e: React.MouseEvent) => { + e.stopPropagation(); window.scrollTo({ top: 0, behavior: 'smooth' }); }; From 52920fbccc91b7884bf35b2d665147fa361e5002 Mon Sep 17 00:00:00 2001 From: WookJin Date: Fri, 19 Jan 2024 13:59:45 +0900 Subject: [PATCH 15/62] Update LikedToursListItem.tsx --- src/components/Trip/LikedToursLists/LikedToursListItem.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index 70d0c6f2..b0a1092b 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -106,7 +106,7 @@ const LikedToursListItem: React.FC = ({
diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index 3ae8f972..de746353 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -1,37 +1,53 @@ import * as Tabs from '@radix-ui/react-tabs'; +import { useRecoilState } from 'recoil'; +import { tapState } from '@recoil/plan'; interface TabProps { lists: string[]; contents: React.ReactNode[]; } -const Tab = ({ lists, contents }: TabProps) => ( - - - {lists.map((list, index) => { +const Tab = ({ lists, contents }: TabProps) => { + const [, setTapState] = useRecoilState(tapState); + + const handleTabChange = (value: string) => { + const tabIndex = value.replace('tab', ''); + if (tabIndex !== '') { + setTapState(tabIndex); + } + }; + + return ( + + + {lists.map((list, index) => { + return ( + + {list} + + ); + })} + + {contents.map((content, index) => { return ( - - {list} - + {content} + ); })} - - {contents.map((content, index) => { - return ( - - {content} - - ); - })} - -); + + ); +}; export default Tab; diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 50c9e2d6..78928526 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -83,6 +83,7 @@ export const useSocket = (tripId: string, visitDate: string) => { useEffect(() => { socketConnect(); + console.log('소켓연결'); return () => { socketClient.deactivate(); diff --git a/src/recoil/plan.ts b/src/recoil/plan.ts index c938efaa..42e69971 100644 --- a/src/recoil/plan.ts +++ b/src/recoil/plan.ts @@ -9,3 +9,8 @@ export const dateState = atom({ key: 'dateState', default: [''], }); + +export const tapState = atom({ + key: 'tapState', + default: '', +}); diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts index d722c733..ab7bb76b 100644 --- a/src/recoil/socket.ts +++ b/src/recoil/socket.ts @@ -10,7 +10,7 @@ export const visitDateState = atom<{ visitDate: string } | null>({ default: { visitDate: '2024-01-03' }, }); -export const memberIdState = atom<{ memberId: number } | null>({ +export const memberIdState = atom<{ token: number | null }>({ key: 'memberIdState', - default: { memberId: 1 }, + default: { token: null }, }); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index a48c16dc..e679617b 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -19,9 +19,9 @@ const SocketRoutes = () => { return ( - } /> - } /> - } /> + } /> + } /> + } /> ); @@ -33,7 +33,7 @@ const SocketRouter = () => { }> } /> } /> - } /> + } /> ); From 98abf65ad7c7381fefe8805e6490a0d46454810b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Fri, 19 Jan 2024 18:27:57 +0900 Subject: [PATCH 17/62] =?UTF-8?q?Fix:=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=EC=97=90=20=ED=86=A0=ED=81=B0=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EB=84=A3=EC=96=B4=20=EC=8B=A4=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=ED=8E=B8=EC=A7=91=EC=A4=91=EB=A9=A4=EB=B2=84=20=EB=94=94?= =?UTF-8?q?=EB=B2=84=EA=B9=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/socket.types.ts | 2 +- src/api/socket.ts | 1 - src/components/Plan/PlanSectionTop.tsx | 14 +++++--- src/components/Trip/TripRealtimeEditor.tsx | 42 ++++++++++++++-------- src/hooks/useSocket.ts | 1 + src/recoil/socket.ts | 4 +-- 6 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index 128a9d20..5b9697ef 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -128,7 +128,7 @@ interface pubDeleteItem { } interface pubMember { - memberId: number; + token: string; } interface pubGetPathAndItems { diff --git a/src/api/socket.ts b/src/api/socket.ts index 6d70c14c..2f84b64c 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -140,7 +140,6 @@ export const pubConnectMember = (pubMember: pubMember, tripId: string) => { destination: `/pub/trips/${tripId}/connectMember`, body: JSON.stringify(pubMember), }); - console.log('펍실행', pubMember); }; // 멤버 여정 페이지 퇴장 이벤트 발생시 diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 9d24dd6f..e37c6089 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -12,20 +12,24 @@ import { useRecoilValue } from 'recoil'; import { tripIdState, memberIdState } from '@recoil/socket'; import { calculateDayAndDate } from '@utils/utils'; import { TripSchedule } from '@components/Trip/TripSchedule'; +import { getItem } from '@utils/localStorageFun'; const PlanSectionTop = () => { const navigate = useNavigate(); const tripId = useRecoilValue(tripIdState); - const pubMember = useRecoilValue(memberIdState); + const token = getItem('accessToken'); + const pubMember = { token: token || '' }; - if (!pubMember || !tripId) { - return
에러
; - } + // if (!pubMember.token || !tripId) { + // return
에러
; + // } const { callBackPub, tripInfo } = useContext(socketContext); useEffect(() => { - callBackPub(() => pubEnterMember(pubMember, tripId)); + if (pubMember && tripId) { + callBackPub(() => pubEnterMember(pubMember, tripId)); + } }, []); let DayArr: string[] = []; diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index d151ed59..4d810455 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -1,38 +1,50 @@ import { useRecoilValue } from 'recoil'; -import { tripIdState, memberIdState } from '@recoil/socket'; -import { useEffect } from 'react'; +import { tripIdState } from '@recoil/socket'; +import { useEffect, useState } from 'react'; import { socketContext } from '@hooks/useSocket'; import { useContext } from 'react'; import { pubConnectMember, pubDisconnectMember } from '@api/socket'; import { UserIcon } from '@components/common/icons/Icons'; import { Swiper, SwiperSlide } from 'swiper/react'; import { Navigation } from 'swiper/modules'; +import { getItem } from '@utils/localStorageFun'; const TripRealtimeEditor = () => { const tripId = useRecoilValue(tripIdState); - const pubMember = useRecoilValue(memberIdState); - if (!pubMember || !tripId) { - return
에러
; - } - const { callBackPub, tripMember } = useContext(socketContext); + const [token, setToken] = useState(''); + const [pubMember, setPubMember] = useState({ token: '' }); - console.log('pubMember', pubMember); useEffect(() => { - callBackPub(() => pubConnectMember(pubMember, tripId)); - return () => { - callBackPub(() => pubDisconnectMember(pubMember, tripId)); - }; + const accessToken = getItem('accessToken'); + if (accessToken) { + setToken(accessToken); + } }, []); - const tripMemberData = tripMember?.data; + useEffect(() => { + setPubMember({ token: token || '' }); + }, [token]); + useEffect(() => { + if (pubMember && tripId) { + callBackPub(() => { + pubConnectMember(pubMember, tripId); + }); + return () => { + callBackPub(() => pubDisconnectMember(pubMember, tripId)); + }; + } + }, [pubMember]); + + const tripMemberData = tripMember?.data; + useEffect(() => { + console.log('tripMemberData', tripMemberData); + }, [tripMemberData]); return (
console.log('slide change')} - onSwiper={(swiper) => console.log(swiper)} navigation={true} modules={[Navigation]} className="flex w-[375px] items-center justify-center"> diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 50c9e2d6..ba204b5b 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -63,6 +63,7 @@ export const useSocket = (tripId: string, visitDate: string) => { subMember(tripId, (res) => { if (res) { + // console.log('subMemberRes', res); setTripMember(res); } }); diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts index d722c733..ab7bb76b 100644 --- a/src/recoil/socket.ts +++ b/src/recoil/socket.ts @@ -10,7 +10,7 @@ export const visitDateState = atom<{ visitDate: string } | null>({ default: { visitDate: '2024-01-03' }, }); -export const memberIdState = atom<{ memberId: number } | null>({ +export const memberIdState = atom<{ token: number | null }>({ key: 'memberIdState', - default: { memberId: 1 }, + default: { token: null }, }); From f54530a4b8939bcdc87cd8bfa25bce02fe781742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Fri, 19 Jan 2024 18:45:02 +0900 Subject: [PATCH 18/62] =?UTF-8?q?Fix:=20=EC=95=84=EC=BD=94=EB=94=94?= =?UTF-8?q?=EC=96=B8=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/PlanTripButton.tsx | 11 ++++++++++- src/components/Trip/TripInfo.tsx | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/Trip/PlanTripButton.tsx b/src/components/Trip/PlanTripButton.tsx index db7b4639..34ce58a5 100644 --- a/src/components/Trip/PlanTripButton.tsx +++ b/src/components/Trip/PlanTripButton.tsx @@ -1,8 +1,17 @@ import { PlanColorIcon, RightIcon } from '@components/common/icons/Icons'; +import { useNavigate } from 'react-router-dom'; const PlanTripButton = () => { + const navigate = useNavigate(); + + const handleButtonClick = () => { + navigate('plan'); + }; + return ( - ); diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 34987b1f..f0097365 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1499,3 +1499,35 @@ export const PaperIcon: React.FC = ({}) => { ); }; + +export const PlanColorIcon = () => { + return ( + + + + + + + ); +}; From 6d7425ad0117e9b06f46a91699c66443ecbd0616 Mon Sep 17 00:00:00 2001 From: sue Date: Fri, 19 Jan 2024 18:48:15 +0900 Subject: [PATCH 20/62] =?UTF-8?q?Design:=20=ED=8E=B8=EC=A7=91=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripInfo.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/Trip/TripInfo.tsx b/src/components/Trip/TripInfo.tsx index 5594c89a..902263e6 100644 --- a/src/components/Trip/TripInfo.tsx +++ b/src/components/Trip/TripInfo.tsx @@ -113,9 +113,6 @@ const TripInfo = () => { 5
-
23.12.23 - 23.12.25
From bf75a5d2702e932d42cd3cf975c40ea3c4d413e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=96=B4=EC=8A=B9=EC=A4=80?= Date: Fri, 19 Jan 2024 18:49:08 +0900 Subject: [PATCH 21/62] =?UTF-8?q?Fix:=20build=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripSchedule.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index 878d730a..ad55e20e 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -1,5 +1,4 @@ import { UserIcon } from '@components/common/icons/Icons'; -import { ReactComponent as NullUser } from '@assets/images/NullUser.svg'; export const TripSchedule = () => { return ( From e5e954b76d29b42406103d174771e6d1aaffcd09 Mon Sep 17 00:00:00 2001 From: Hojin Date: Fri, 19 Jan 2024 18:50:39 +0900 Subject: [PATCH 22/62] =?UTF-8?q?Feat:=20=EA=B6=8C=ED=95=9C=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EC=BB=A4=EC=8A=A4=ED=85=80=ED=9B=85=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/trips.types.ts | 10 +++++++ src/api/trips.ts | 6 ++++ src/components/Trip/TripSectionTop.tsx | 2 ++ src/hooks/useGetTripsAuthority.ts | 39 ++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/hooks/useGetTripsAuthority.ts diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index fb708de8..9aa18b2d 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -18,3 +18,13 @@ interface MyTripType { area: string; subArea: string; } + +interface AuthorityType { + status: number; + message: string; + data: { + memberId: number; + tripAuthority: string; + TripId: number; + }; +} diff --git a/src/api/trips.ts b/src/api/trips.ts index be019a7f..f327e7a3 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -84,3 +84,9 @@ export const getTripsMembers = async (tripId: number) => { const res = await client.get(`trips/${tripId}/members`); return res; }; + +// 편집권한 조회 +export const getTripsAuthority = async (tripId: string) => { + const res = await authClient.get(`trips/${tripId}/authority`); + return res; +}; diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index 82e03c8e..4f1062eb 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -5,9 +5,11 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import PlanTripButton from './PlanTripButton'; import { LikedToursList } from './LikedToursList'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; const TripSectionTop = () => { const navigate = useNavigate(); + const { tripAuthority } = useGetTripsAuthority(); return (
diff --git a/src/hooks/useGetTripsAuthority.ts b/src/hooks/useGetTripsAuthority.ts new file mode 100644 index 00000000..efef5695 --- /dev/null +++ b/src/hooks/useGetTripsAuthority.ts @@ -0,0 +1,39 @@ +import { useQuery } from '@tanstack/react-query'; +import { getTripsAuthority } from '@api/trips'; + +import { useParams } from 'react-router-dom'; + +type useGetTripsAuthorityReturn = { + tripAuthority: string | null; + memberId: number | null; + TripId: number | null; +}; + +export const useGetTripsAuthority = (): useGetTripsAuthorityReturn => { + const { id } = useParams(); + + const defaultReturn = { + tripAuthority: null, + memberId: null, + TripId: null, + }; + + if (!id) { + return defaultReturn; + } + const { data, isLoading, isError } = useQuery({ + queryKey: ['getTripsAuthority', id], + queryFn: () => getTripsAuthority(id), + enabled: !!id, + }); + + const tripAuthority = data?.data.data.tripAuthority; + const memberId = data?.data.data.memberId; + const TripId = data?.data.data.TripId; + + if (isLoading || isError) { + return defaultReturn; + } + + return { tripAuthority, memberId, TripId }; +}; From 66a51b8b63ca0775129cad73210865d82d765d23 Mon Sep 17 00:00:00 2001 From: Hojin Date: Fri, 19 Jan 2024 21:20:10 +0900 Subject: [PATCH 23/62] =?UTF-8?q?Feat:=20pubGetPathAndItems=20=EB=94=94?= =?UTF-8?q?=ED=8E=9C=EB=8D=98=EC=8B=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanItem.tsx | 13 ++----------- src/components/Plan/PlanSectionTop.tsx | 16 ++-------------- src/components/common/tab/Tab.tsx | 4 +--- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 49c410f4..f0965d42 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -15,10 +15,9 @@ import { tapState } from '@recoil/plan'; type PlanItemProps = { date: string; day: string; - isMount: boolean; }; -const PlanItem: React.FC = ({ date, day, isMount }) => { +const PlanItem: React.FC = ({ date, day }) => { const navigate = useNavigate(); const [isEdit, SetIsEdit] = useState(false); @@ -29,21 +28,14 @@ const PlanItem: React.FC = ({ date, day, isMount }) => { const { tripItem, tripPath, callBackPub } = useContext(socketContext); useEffect(() => { - if (isMount) { + if (tap) { setVisitDate({ visitDate: date }); if (date && tripId) { callBackPub(() => pubGetPathAndItems({ visitDate: date }, tripId)); - console.log('pubGetPathAndItems', tap); } } }, [tap]); - // useEffect(() => { - // if (date && tripId) { - // callBackPub(() => pubGetPathAndItems({ visitDate: date }, tripId)); - // } - // }, [tap]); - const handleEdit = () => { SetIsEdit((prev) => !prev); }; @@ -68,7 +60,6 @@ const PlanItem: React.FC = ({ date, day, isMount }) => { const transpo = tripItem?.data?.transportation || ''; - // console.log(tripItem?.data?.tripItems.sort((a, b) => a.seqNum - b.seqNum)); return ( <> {tripPath && } diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 81079cfe..3f6a9073 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -7,7 +7,7 @@ import PlanItem from './PlanItem'; import { socketContext } from '@hooks/useSocket'; import { useContext } from 'react'; import { pubEnterMember } from '@api/socket'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { useRecoilValue, useRecoilState } from 'recoil'; import { dayState, dateState } from '@recoil/plan'; import { tripIdState, memberIdState } from '@recoil/socket'; @@ -15,22 +15,15 @@ import { calculateDayAndDate } from '@utils/utils'; const PlanSectionTop = () => { const navigate = useNavigate(); - const [isMount, setIsMount] = useState(false); const tripId = useRecoilValue(tripIdState); const pubMember = useRecoilValue(memberIdState); const [, setDay] = useRecoilState(dayState); const [, setDate] = useRecoilState(dateState); - console.log(isMount); - if (!pubMember || !tripId) { return
에러
; } - useEffect(() => { - setIsMount(true); - }, []); - const { callBackPub, tripInfo } = useContext(socketContext); useEffect(() => { @@ -66,12 +59,7 @@ const PlanSectionTop = () => { ( - + ))} />
diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index de746353..ab864b34 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -12,9 +12,7 @@ const Tab = ({ lists, contents }: TabProps) => { const handleTabChange = (value: string) => { const tabIndex = value.replace('tab', ''); - if (tabIndex !== '') { - setTapState(tabIndex); - } + setTapState(tabIndex); }; return ( From 528fb995d046278feee749ec33448fc9cd1144aa Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Fri, 19 Jan 2024 21:43:07 +0900 Subject: [PATCH 24/62] =?UTF-8?q?style:=20=EC=84=B8=EB=B6=80=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MyTrip/MyTripItem.tsx | 2 +- src/components/Trip/LikedToursLists/LikedToursListItem.tsx | 4 ++-- src/components/common/icons/Icons.tsx | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/MyTrip/MyTripItem.tsx b/src/components/MyTrip/MyTripItem.tsx index a91a0a2f..2762a3d1 100644 --- a/src/components/MyTrip/MyTripItem.tsx +++ b/src/components/MyTrip/MyTripItem.tsx @@ -59,7 +59,7 @@ const MyTripItem: React.FC = ({ myTripList }) => {
여행지 이미지 diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index b0a1092b..80744836 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -106,7 +106,7 @@ const LikedToursListItem: React.FC = ({ + {tripAuthority !== 'WRITE' ? ( + '' + ) : ( + + )}
@@ -117,7 +122,7 @@ const PlanItem: React.FC = ({ date, day }) => { )}
- {isEdit ? ( + {tripAuthority !== 'WRITE' || isEdit ? ( '' ) : ( = ({
{day.map((day, index) => ( - +
- {targetBudget.toLocaleString()} + {budget?.budget.toLocaleString()}
diff --git a/src/components/Plan/TripMap.tsx b/src/components/Plan/TripMap.tsx index 9816403e..02c3787a 100644 --- a/src/components/Plan/TripMap.tsx +++ b/src/components/Plan/TripMap.tsx @@ -100,8 +100,6 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { // 선택된 마커의 인덱스를 추적하기 위한 상태 const [selectedMarker, setSelectedMarker] = useState(null); - // ... - // 마커를 클릭할 때 호출되는 함수 const handleMarkerClick = (index: number) => { setSelectedMarker(index); @@ -127,14 +125,12 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { svgComponent = isSelected ? FifthSelectedMarker : FifthMarker; break; default: - // 기본 마커가 필요한 경우 기본 마커 이미지 URL을 제공합니다. + // 기본 마커 return 'default_marker_image_url'; } return svgComponent; }; - // ... TripMap 컴포넌트 및 나머지 코드 - return (
Date: Fri, 19 Jan 2024 23:09:24 +0900 Subject: [PATCH 27/62] =?UTF-8?q?Design:=20Tab=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EB=B6=80=20css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/tab/Tab.tsx | 58 +++++++++++++++++++------------ 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index 3ae8f972..96effc11 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -5,33 +5,45 @@ interface TabProps { contents: React.ReactNode[]; } -const Tab = ({ lists, contents }: TabProps) => ( - - - {lists.map((list, index) => { +const Tab = ({ lists, contents }: TabProps) => { + let isDayTab = false; + + lists.forEach((list) => { + if (list.includes('DAY')) { + isDayTab = true; + } + }); + + return ( + + + {lists.map((list, index) => { + return ( + + {list} + + ); + })} + + {contents.map((content, index) => { return ( - - {list} - + {content} + ); })} - - {contents.map((content, index) => { - return ( - - {content} - - ); - })} - -); + + ); +}; export default Tab; From ed00ab5dce8e0ecf89b82ae00f6b55c7b903fc05 Mon Sep 17 00:00:00 2001 From: NohWookJin Date: Fri, 19 Jan 2024 23:22:16 +0900 Subject: [PATCH 28/62] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=EC=8B=9C=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LikedToursLists/LikedToursListItem.tsx | 12 +++-- src/components/common/icons/Icons.tsx | 54 +++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index 80744836..8fb54656 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -1,4 +1,10 @@ -import { ThumbsUp, ThumbsDown, StarIcon } from '@components/common/icons/Icons'; +import { + ThumbsUp, + ThumbsDown, + ClickThumbsUp, + ClickThumbsDown, + StarIcon, +} from '@components/common/icons/Icons'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { postTripsLikeHate } from '@api/trips'; import { useNavigate } from 'react-router-dom'; @@ -106,7 +112,7 @@ const LikedToursListItem: React.FC = ({ } content={ @@ -104,7 +130,7 @@ const TripBudget = () => { />
- {budget?.budget.toLocaleString()} + {budget?.budget.toLocaleString() ?? '- '}
From d4eceb9ebec963ae5463cb83cf8bc5c09238263f Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 20 Jan 2024 00:35:08 +0900 Subject: [PATCH 31/62] =?UTF-8?q?Chore:=20=EB=B9=8C=EB=93=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanItem.tsx | 3 ++- src/components/Trip/TripSectionTop.tsx | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 49c410f4..a49109f6 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom'; import TripMap from './TripMap'; import PlanItemBox from './PlanItemBox'; import PlanEditItemBox from './PlanEditItemBox'; -import { useContext, useEffect, useState, useRef } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { socketContext } from '@hooks/useSocket'; import { useRecoilState, useRecoilValue } from 'recoil'; import { visitDateState } from '@recoil/socket'; @@ -27,6 +27,7 @@ const PlanItem: React.FC = ({ date, day, isMount }) => { const [visitDate, setVisitDate] = useRecoilState(visitDateState); const { tripItem, tripPath, callBackPub } = useContext(socketContext); + console.log(visitDate); useEffect(() => { if (isMount) { diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index 4f1062eb..59ef58eb 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -11,6 +11,8 @@ const TripSectionTop = () => { const navigate = useNavigate(); const { tripAuthority } = useGetTripsAuthority(); + console.log(tripAuthority); + return (
Date: Sat, 20 Jan 2024 00:58:02 +0900 Subject: [PATCH 32/62] =?UTF-8?q?Fix:=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanEditItemBox.tsx | 6 +++--- src/components/Plan/PlanItem.tsx | 14 +++++++------- src/components/Plan/PlanMoveItem.tsx | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/components/Plan/PlanEditItemBox.tsx b/src/components/Plan/PlanEditItemBox.tsx index a3987601..e5b0f944 100644 --- a/src/components/Plan/PlanEditItemBox.tsx +++ b/src/components/Plan/PlanEditItemBox.tsx @@ -106,7 +106,7 @@ const PlanEditItemBox = ({ {(provided) => (
-
{day}
+
{day}
{items.map((item, index) => ( -
-
+
+
선택한 장소를 삭제하시겠습니까?} diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index c3eb94ff..996ddbec 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -24,7 +24,6 @@ const PlanItem: React.FC = ({ date, day }) => { const [isEdit, SetIsEdit] = useState(false); const tripId = useRecoilValue(tripIdState); const tap = useRecoilValue(tapState); - const [visitDate, setVisitDate] = useRecoilState(visitDateState); const { tripItem, tripPath, callBackPub } = useContext(socketContext); @@ -121,10 +120,11 @@ const PlanItem: React.FC = ({ date, day }) => { /> )}
-
- {tripAuthority !== 'WRITE' || isEdit ? ( - '' - ) : ( + + {tripAuthority !== 'WRITE' || isEdit ? ( +
+ ) : ( +
navigate('./place')} className="h-[40px] w-full"> @@ -133,8 +133,8 @@ const PlanItem: React.FC = ({ date, day }) => {
장소 추가하기
- )} -
+
+ )} ); }; diff --git a/src/components/Plan/PlanMoveItem.tsx b/src/components/Plan/PlanMoveItem.tsx index 66910d1c..b06df513 100644 --- a/src/components/Plan/PlanMoveItem.tsx +++ b/src/components/Plan/PlanMoveItem.tsx @@ -7,7 +7,6 @@ import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; import { useState, useEffect } from 'react'; import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; -import { v4 as uuidv4 } from 'uuid'; interface PlanMoveItemProps { isCheck: number | null; From a0a37b27487b5767f012a38f9ebb9b79e842407c Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 02:04:08 +0900 Subject: [PATCH 33/62] =?UTF-8?q?Refactor:=20=ED=8E=B8=EC=A7=91=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9A=94=EC=B2=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/trips.ts | 4 ++-- src/pages/share/share.page.tsx | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/api/trips.ts b/src/api/trips.ts index b2803936..c9c42736 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -70,13 +70,13 @@ export const getTripsSurvey = async (tripId: number) => { }; // 여정 참여 코드 조회 -export const getTripsjoin = async (tripId: number) => { +export const getTripsjoin = async (tripId: string) => { const res = await authClient.get(`trips/${tripId}/join`); return res; }; // 여정 참여 export const postTripsjoin = async (tripId: number, joinCode: string) => { - const res = await client.post(`trips/${tripId}/join`, { joinCode }); + const res = await authClient.post(`trips/${tripId}/join`, { joinCode }); return res; }; diff --git a/src/pages/share/share.page.tsx b/src/pages/share/share.page.tsx index afa87318..ecd87444 100644 --- a/src/pages/share/share.page.tsx +++ b/src/pages/share/share.page.tsx @@ -2,25 +2,33 @@ import { getTripsjoin } from '@api/trips'; import CopyBox from '@components/Share/CopyBox'; import { BackBox } from '@components/common'; import { useEffect, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; const Share = () => { const navigate = useNavigate(); const [joinCode, setJoinCode] = useState(null); + const params = useParams(); + const tripId = params.id; useEffect(() => { const getTripCode = async () => { - try { - const { data } = await getTripsjoin(27); - if (data.status === 200) { - setJoinCode(data.data); + if (tripId) { + try { + const { data } = await getTripsjoin(tripId); + if (data.status === 200) { + setJoinCode(data.data); + } + } catch (err) { + console.error('편집 참여 코드 요청 중 에러 발생', err); } - } catch (err) { - console.error(err); } }; getTripCode(); }, []); + + const url = window.location.href; + const shareUrl = url.replace('/share', ''); + return (
{ {joinCode && ( Date: Sat, 20 Jan 2024 02:32:50 +0900 Subject: [PATCH 34/62] =?UTF-8?q?Feat:=20=EB=A6=AC=EB=B7=B0=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EB=8D=94=EB=B3=B4=EA=B8=B0=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DetailSectionBottom/DetailReviewStats.tsx | 6 ++-- src/components/Plan/PlanSectionTop.tsx | 1 - src/components/Trip/TripRealtimeEditor.tsx | 20 +++++------ src/components/Trip/TripSchedule.tsx | 3 -- src/components/common/icons/Icons.tsx | 33 +++++-------------- 5 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/components/DetailSectionBottom/DetailReviewStats.tsx b/src/components/DetailSectionBottom/DetailReviewStats.tsx index c428443c..f87f181b 100644 --- a/src/components/DetailSectionBottom/DetailReviewStats.tsx +++ b/src/components/DetailSectionBottom/DetailReviewStats.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useGetToursReviews } from '@hooks/useReviewStats'; import { v4 as uuidv4 } from 'uuid'; -import { DownIcon } from '@components/common/icons/Icons'; +import { DropdownIcon } from '@components/common/icons/Icons'; import useReviewStatsCalculator from '@hooks/useReviewStatsCalculator'; import { getEmoji } from '@utils/utils'; @@ -45,11 +45,11 @@ const DetailReviewStats = () => {
setShowAll(!showAll)} - className="cursor-pointer transition-transform duration-300" + className="mt-[9px] cursor-pointer transition-transform duration-300" style={{ transform: showAll ? 'rotate(180deg)' : 'rotate(0deg)', }}> - +
)} diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 5f99f5d4..114ee5a5 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -13,7 +13,6 @@ import { dayState, dateState } from '@recoil/plan'; import { tripIdState, memberIdState } from '@recoil/socket'; import { calculateDayAndDate } from '@utils/utils'; import { TripSchedule } from '@components/Trip/TripSchedule'; -import { getItem } from '@utils/localStorageFun'; const PlanSectionTop = () => { const navigate = useNavigate(); diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index 4d810455..7c5b9f1a 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -26,16 +26,16 @@ const TripRealtimeEditor = () => { setPubMember({ token: token || '' }); }, [token]); - useEffect(() => { - if (pubMember && tripId) { - callBackPub(() => { - pubConnectMember(pubMember, tripId); - }); - return () => { - callBackPub(() => pubDisconnectMember(pubMember, tripId)); - }; - } - }, [pubMember]); + // useEffect(() => { + // if (pubMember && tripId) { + // callBackPub(() => { + // pubConnectMember(pubMember, tripId); + // }); + // return () => { + // callBackPub(() => pubDisconnectMember(pubMember, tripId)); + // }; + // } + // }, [pubMember]); const tripMemberData = tripMember?.data; useEffect(() => { diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index ad55e20e..c68a60e3 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -12,9 +12,6 @@ export const TripSchedule = () => { 5
-
23.12.23 - 23.12.25 diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index ab793d75..1c66fb80 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1299,7 +1299,6 @@ export const CounterIcon: React.FC< ); }; - export const PlanColorIcon: React.FC = ({ size = 21 }) => { return ( = ({ size = 21 }) => { ); }; - export const ThumbsUp: React.FC = ({ size = 16, fill = '#1E1E1E', @@ -1675,34 +1673,21 @@ export const PaperIcon: React.FC = ({}) => { ); }; -export const PlanColorIcon = () => { +export const DropdownIcon: React.FC = ({}) => { return ( + preserveAspectRatio="xMidYMid meet"> - - - ); }; From 463da03b38cef2b2e734da301171c273b4e94486 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 02:40:09 +0900 Subject: [PATCH 35/62] =?UTF-8?q?Refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/share/share.page.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/share/share.page.tsx b/src/pages/share/share.page.tsx index ecd87444..7d6d5887 100644 --- a/src/pages/share/share.page.tsx +++ b/src/pages/share/share.page.tsx @@ -7,8 +7,7 @@ import { useNavigate, useParams } from 'react-router-dom'; const Share = () => { const navigate = useNavigate(); const [joinCode, setJoinCode] = useState(null); - const params = useParams(); - const tripId = params.id; + const { id: tripId } = useParams(); useEffect(() => { const getTripCode = async () => { From 8ac1555950862a7d4ce76418153311e67b3cc912 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 02:41:58 +0900 Subject: [PATCH 36/62] =?UTF-8?q?Feat:=20=EC=9D=B4=EB=AF=B8=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=91=20=EA=B0=80=EB=8A=A5=ED=95=9C=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/share/shareCode.page.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pages/share/shareCode.page.tsx b/src/pages/share/shareCode.page.tsx index 431f8e90..86909ae8 100644 --- a/src/pages/share/shareCode.page.tsx +++ b/src/pages/share/shareCode.page.tsx @@ -1,10 +1,20 @@ import { postTripsjoin } from '@api/trips'; import { BackBox } from '@components/common'; -import { useState } from 'react'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; const shareCode = () => { const navigate = useNavigate(); + const { tripAuthority, TripId } = useGetTripsAuthority(); + + useEffect(() => { + if (tripAuthority === 'WRITE' && TripId) { + alert('이미 편집 가능한 여정입니다.'); + navigate(`/trip/${TripId}`); + } + }, [tripAuthority, TripId]); + const [inputCode, setInputCode] = useState(''); const [showError, setShowError] = useState(false); @@ -13,9 +23,9 @@ const shareCode = () => { if (changeValue.length <= 5) { setInputCode(e.target.value); } - if (changeValue.length === 5) { + if (changeValue.length === 5 && TripId) { try { - const res = await postTripsjoin(27, changeValue); + const res = await postTripsjoin(TripId, changeValue); console.log(res); } catch (err) { setShowError(true); From d9afea2d2e5e96d1c181c5544232e704e40fab20 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 20 Jan 2024 03:45:09 +0900 Subject: [PATCH 37/62] =?UTF-8?q?Chore:=20=EB=B9=8C=EB=93=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/TripRealtimeEditor.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index 4d810455..895b51e4 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -56,8 +56,8 @@ const TripRealtimeEditor = () => { const imageUrl = isImageUrlValid ? thumbnailUrl : null; return ( - -
+ +
{imageUrl ? ( Date: Sat, 20 Jan 2024 03:45:47 +0900 Subject: [PATCH 38/62] =?UTF-8?q?Feat:=20=EA=B2=BD=EB=B9=84=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B6=8C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/TripBudget.tsx | 110 ++++++++++++++------------- src/components/Trip/TripSchedule.tsx | 3 - 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/components/Plan/TripBudget.tsx b/src/components/Plan/TripBudget.tsx index 07b33ecf..ee1e5388 100644 --- a/src/components/Plan/TripBudget.tsx +++ b/src/components/Plan/TripBudget.tsx @@ -1,6 +1,7 @@ import { pubUpdateBudget } from '@api/socket'; import Alert from '@components/common/alert/Alert'; import { CloseIcon, SettingIcons } from '@components/common/icons/Icons'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; import { socketContext } from '@hooks/useSocket'; import * as Progress from '@radix-ui/react-progress'; import { tripIdState } from '@recoil/socket'; @@ -8,6 +9,7 @@ import { useContext, useState } from 'react'; import { useRecoilValue } from 'recoil'; const TripBudget = () => { + const { tripAuthority } = useGetTripsAuthority(); const { tripBudget } = useContext(socketContext); const tripId = useRecoilValue(tripIdState); @@ -71,63 +73,67 @@ const TripBudget = () => {
목표 경비 - handleSetTargetBudget(inputBudget)} - closeOnConfirm={true} - children={ - + } + content={ +
+
+ setInputBudget(e.target.value)} + /> +
setInputBudget('')}> + {showCloseIcon && ( + + )}
- - - -
- )} - - } - content={ -
-
- setInputBudget(e.target.value)} - /> -
setInputBudget('')}> - {showCloseIcon && }
-
- -
- } - /> + +
+ } + /> + )}
{budget?.budget.toLocaleString() ?? '- '} diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index ad55e20e..c68a60e3 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -12,9 +12,6 @@ export const TripSchedule = () => { 5
-
23.12.23 - 23.12.25 From 61031ec055d5d4cd07b882a9a19a6ffa0a4185d3 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 20 Jan 2024 03:46:23 +0900 Subject: [PATCH 39/62] =?UTF-8?q?Feat:=20=EB=A7=B5=20=EB=A7=88=EC=BB=A4=20?= =?UTF-8?q?=EC=8B=9C=ED=80=80=EC=8A=A4=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/images/FifthMarker.png | Bin 1666 -> 0 bytes src/assets/images/FifthSelectedMarker.png | Bin 1272 -> 0 bytes src/assets/images/FirstMarker.png | Bin 1572 -> 0 bytes src/assets/images/FirstSelectedMarker.png | Bin 1019 -> 0 bytes src/assets/images/FourthMarker.png | Bin 1623 -> 0 bytes src/assets/images/FourthSelectedMarker.png | Bin 1139 -> 0 bytes src/assets/images/SecondMarker.png | Bin 1717 -> 0 bytes src/assets/images/SecondSelectedMarker.png | Bin 1162 -> 0 bytes src/assets/images/ThirdMarker.png | Bin 1711 -> 0 bytes src/assets/images/ThirdSelectedMarker.png | Bin 1254 -> 0 bytes src/components/Plan/TripMap.tsx | 108 +++++++++++---------- src/components/common/icons/Icons.tsx | 49 ++-------- src/utils/getColor.ts | 7 ++ 13 files changed, 72 insertions(+), 92 deletions(-) delete mode 100644 src/assets/images/FifthMarker.png delete mode 100644 src/assets/images/FifthSelectedMarker.png delete mode 100644 src/assets/images/FirstMarker.png delete mode 100644 src/assets/images/FirstSelectedMarker.png delete mode 100644 src/assets/images/FourthMarker.png delete mode 100644 src/assets/images/FourthSelectedMarker.png delete mode 100644 src/assets/images/SecondMarker.png delete mode 100644 src/assets/images/SecondSelectedMarker.png delete mode 100644 src/assets/images/ThirdMarker.png delete mode 100644 src/assets/images/ThirdSelectedMarker.png create mode 100644 src/utils/getColor.ts diff --git a/src/assets/images/FifthMarker.png b/src/assets/images/FifthMarker.png deleted file mode 100644 index 617795ce56b3d98b24c7c8f88a7932e57d347881..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1666 zcmV-|27UR7P)B4I2nm;{U?&LdC^$BBRW5Us+N2RK-ce%w!Yio5ut{}QD2;oS`|8)1L+wEqe zC^C!1La$%HPT@0s!-fs|z`y_}22mh9em4D7LrED&P3<4N24mUy!NU^O=(=pKZP~LPoW~-48^m%>Kr+UEu?R-42I?Mx#**L{JeFfbv)P>JT<) zhq3-Gufa(z$pNq8A~jM;*5MQ_xjrM}BIk?ZQ;n6nu3JG71rnVMk(bV@=@12vCHocW zRgwn}NsgJn4vdhW64yvEu=i|SA6>WSAf;59o}Ny^5WxZz1>j1ceJ~XhNnAOf2}8O{ z%0-1MFkgsn=OeI=5{t!T$R9F0iZew~%+$@&A$sHaZ2_>$5kH2QO7ekD-|@l1n36Ff^vTIdQdL#O6I425LfkT@(ZO7kj6ov0N~8SzxVw$} zLBDHF+7}K)&*vv`_M#7z!1B&hcXf3&f&PU1qe+56i0VQxF_>?n_5Tj@tccR@0ut@E zr93)%LVtpvOyvGBsZIsA?LUKDfPf~;vIbG2V@2hO(tHnYh%n?u*Nzmdo=wnHnc;aw zkMLtYXd|QVhc|t643vmKMGcpfltdv}rSK8UEFyRgwL|)A=QGQt<`uueEho7TV1ei# zft6c3;g4gfR4QCvULJ#1Ft&R2Y8A|Z&dJg~fp$Viso4I_xb6?VP3{N44AGB|^ugRo z=sy#nLK31Q1xlE`=WNGBAT!8h)Y9JjBe@lNhb#m@Al`fEE$#c^2_TU`Kogt<0$O8Z zBh7p@YkSw!)Px<7;yUqRvvt+OhnOVRkRrf>F<`h?bn|yBVZval2G;HNO;>MvoL%;BCmNkBxOgajCV6~hOK|1Z*Au^v-T)IsfItis zh#3Slv%k#T0%TRfcnJxL9*+krp9MVIYW?=zwNmYaYoN2P5v)qJPW3Rz9$~jb|0D*6 zevW=|;wqVGR8+g&o&o|%Pyl@(We}hkmSoOGDDS=lyKXG;6B841Boa};yA|vQpbBET zpIeA@BO6j6t-4$;6$ofhA2djW+R)Gt&DfC@1p)I1lw4d)fh=c-2*P>}ErGKFB(8+< z01gN}H{Js{K|RdtHrV(m_&q7G-JI`Ul)ndL#PRWQ5qd=I2LvF+?}IV|ZUG?^G7LY+ zhOEB6UN`bU!M~pu31ch3%yV;NjC)k<70p6~Fc;4B{{It2ZU6J(Kgc2hc4|6Cng9R* M07*qoM6N<$f+z<1rT_o{ diff --git a/src/assets/images/FifthSelectedMarker.png b/src/assets/images/FifthSelectedMarker.png deleted file mode 100644 index b931eb7b0dcdb5bab5f83bf9681c3b93bc97c38a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmV8=z#Uj-Mh z@vG^6x{_4r98Z~jn~e$;>ie|aJSK1OxpMZ)`A8)C%J)Z@N~><2UrO}Qbk8tNW`-P_ zyHRND)19Ng>E4T?*LF+g?D$uKB>W`s?b-Kf`pkQQo4c{yJfgAZtEVI*4R>L8U}Dyn zM1SetmYo1LT~X%}SWYsUxe&NeRc)9jgW!Q_=DuGiZ8S!_~GH@wzHgJ)uaSHhxF0YuU zf+`@HFqQPOw7YAN%LwKQ&u0P`K_mnoo;=k;IJ^k&v?Ao1Ny-miQ8y_BRqSySiv)#d z!*D;4YWp#PL!@_#49Jt6AQsf`*{p!dESlBSmFvH%g+l-h|Wv739gUe*{vwhOz5E56@ zecGl-Ot-2}=!e5iEn5PR$Y|!G@4I%g8VA8P@JyoglG(FJdcb-pbsA(B-^geR4}m1? zHG|7-M!W# zBcaGdlJ2f=8A+^HO5u-pJ_+^tc5qv&4XU$XRasgVt>C^O#G)|_X-w^}hx&X}{C=|I zB*0jOQ`4+B&7!7ul3rkBc?t{&2G=PO82YV)C(cgMT(n;U+%;xSuQ5$T4aZ)9@xqJj zz(IGj6GQesZf{6-Yr>`$0B(i20C9!|A_F)*Lb#hii-daZbe{{Fk#^Nq30FN2pfJ(y z9Vta7Bg>89DNx~K>4tu>#$Dk0k^qoig;b01x%|X~I$zG-nDZL(y$1SSg5p5trnTMd z_%*+A?l-W9m@b;L)G+}ncAuoig68m`L20N<&?9v~0EQU$-6D_#&@v=-p4x;#Andb% zJ~tZrOLyla=X{j8?GVuCM@JMQ?Gn)6X%9g};tatk~vLJOV%00003m-M*y-T9!v^Qx!BwPy-2K6YvT0LsKGAF`D?`heCjaUxbp#FTltTR3yY` z3?vX^1QkLgEd&B$>mO_-gvgc_s_oL(vXAb}-0OFCcb4sg?zW{Tncbb)JNJC|JLi7q zT%t*sQc4WFr-_&`j+7|}ix<1_JGW`xx<}jRz4a1b{<&|y zyuV`kY&nav2op&o;^?y9#Jl_<|% zoy2m=(*Bi^&&u1r+k>AmuoKJA&o}*kzYSLGWQaz9&_0NWaHsDY2bDq= zYtsz(MnPikm^1sP5q@?I0$}# zZ6pxOHTRvZ&`Y#&HPJbw$_q~tEvX@TY<4CLNIFrlw`j?F2%8%~a`0_*badz(`qY@D z3~MLbtDkcz?UVb?wy2V5_d7%#cZga$5{&TgA1-FXLHWWp>(jnJkLbE?!Iy>Pw2>P! z#RRhg=@o|5YBSEZ?`NXbVB*#t8js}&y<(+jPB9kj!Y(mp%$T9o*47RQ2Zw@HYvGtP zUAmS4F%YJS*eiKHAN%uqy*k38feGP+gh8kTs*!U1AgxT#DFhQ7evLukkzfUNKqO7{ z(G;4UbdtQNy1F`Eo8ll?BT)U6B>N^!p#|({5LyvmIjeV3QPGgZRGbr%l%J-^EK+y3 z1}Ul35N##=Ksq1^1BD-ye&$?VL8%)>$5swV|6Q}7(#S*-?A!tiHW;y?o+;fHPLGHkq969pUQsT*r!vkuA4*y1No-dZt}!gC zWT(e}@KrbtfeEgtA@muM>({Sy(-UV!bD9iJ&gI6%#t2zoP$p|_Pv}Ml0BoE3E^PpS z7#N7*HioXt=A^{p?4r_Rq!%dEHe$MOFOZC!Ufp88@&=|m?|9<=u&LXH8Ve}KBii(Ozd3m|n)YQbG z7@C-ACQ;I@H{|dCeBS@}vVIl&n#O51$>8zG&8+~iA0Y@c09+A-o0+h%HF<}q^s~xv z5Q@(XC@|KRo^yd>|2NxChi|WlC_7`RWan3{z5}ZQzpbk4Idc-bAp{U1FT)=D}*6d7;S+n``!XpL%$iyKLD*!t;2ZX3Xa?VP)Mml?+~r zbu}F7zk2mlq^*}&n~;Ecd3l_Kg8;x?w*x?C)$*q(!PezAthKdO4+H|P!NEb7Wmzt? zYA!B9T#S-T@*F%dJ768KLZOh!jsd_z1H)$z$%#K2fKi!9p-a3VA!G^%AeLDhVFJsh zj)RSc4A;{Zq2Qe5SR(!s@#nLKg!ahx_Vy7ukTnydj1!nt<3<&%2#AfqmX5yj}Kv|qcvjX9$s*_V(g1H;x!pFS`3mrdCbL^bnCw>^t(o(&_WbJ=x W>DWepKX!Tm00008B}=VLIKh3W#sm9sQ04G+s!Kw^qy4$@yf89 z-b*{XrqBH{!mfu|wJmYFX$=!X$_ZrvTOmyA8vtVu0M6erUtwZP@WWYRYh(=wsokU{ z*cJ;M1DuXQ;$ZWN{4l8yY>i6>1c*Nw<-%whLdDU}pix|A7eAny=4lfGP*VmDLYlk!+~1+89cA;M|*kHzlz zuJr8eK}Y4vC{ZH_sVjY-HlU;8?cP!i^(R$9mCqYx(0T_U*b2PWTdMM#Xp~-ht9#{h z=i4q(lKsPEI>Zp#veh_WPeI`b+R zWxIFY6S2}PfDH)LD>XVh%qi5l`NMO|O4VTndf+;=>djVBV_L%&8yrBqNwo{Yfqwg? z+9zSoehhHdn3+b6X^BnFK2NfeJ|`F4Uvl>9xV6x0?{HV!eN!bOop$yc`vq^sQDFG# zA1`~SyTo4SVaTK8&(hiQC|kpOPahvPvtpn}-HdnO*002ovPDHLkV1ln?z=r?; diff --git a/src/assets/images/FourthMarker.png b/src/assets/images/FourthMarker.png deleted file mode 100644 index f1963795bd5e844e9b503d473731683a8b766e82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1623 zcmV-d2B`UoP)LGS@v9|$d0u~u43Y;D=K>}_s`|KFKehV6DcZTXUuGw00gIp6v3 zX94B`Aq2}C!(1TG;#+2K!WheKNJMCy&ktq+R_vv2#X) z_V(sBZEbBesBda&5_|US5f-@_39%vsvhNAFIP2@{lW;@ceV{U09pq7ZsT;sLe$g+# zcw!>HaN$BBNs>`gQlbwI4iXuot*y;KGDZPOxg&uKaNLv)3=HsdJBOe3$>JG_!*YC8 zp8u_?!R3GB;^_H)^}_a##UPT=CnhFT;)w^)PoF+**k^M^!WKQU=dn+!T0#LhjuZ9Z z0-7O)N5T3ai~Nh5hWZBt5>gHHE>>i#cPPVJ4K`3-I8+ z+vDW5qMxH%m+e^Rd+6)#SO@1^NhA_7#vJmNT>Rh^4#^ho39%=@4OX?Az4|}6#frtA z_1Jk0!|hi znF2j9jA-Pm(V{ES=8cyA&#i~qfK;+(xxXAqNWoxGLTT`>uC83nAQA#up&(ee=t@Mu z69Tw$03b00v&H>UZwO5Fb8GXQMzSKIj97Gq`i*8IHT1m)bAqmcg8*e(>P$({WLa66 z(1men+68PikOY>#X14NW=3IE0Ii3L@eXm}}SYfAT;rIK=C$eMN3ZFu3kNjOYlYnUt zgvi5YbArfFBQ;Hf8#l$TXa~aQ^O0L-Gb%<;>P!+uhIDfy&AzD$!b=5LDP)LCwgA*V z3NUt|C;`I6P4T(w)vjN$Qk42&0KhvE*Kz&IhQpBp`keBuRH8T)x^Q>-{ac0%JK zIQVVyB&tHkM-^)gjfh~H&&6$K*NDx{&GOluL$3t9upiu@91Y78Hti%iy|-K&H#+LK z{kIEMkw8gIE?BT2QBzZs#@IyJG^-kJ)sR5O`M?|A4^%jjk<7TFxwPKM+W8li~ZVmL$GUb7jWuA=B*=Vl7mPfjcQ1v6jVIy zlzPG}hi{kdM9S0IREPyA^{iYmRvoG-#8es}s60594G#X7|(>gml z$v*BhOxsPtl!&(JSjoVdOUmPEO}I}G7Dxr}ccizieLMN3O+c3A6y}ReWo4y~;hNl3 zI4kh{%THD<7(vy?_VxUU<4u1ZiEOT|U|YR1G{Fp~|6@e^;?)zW&wjk3PoOuXOG`^h z4H@du7*&i7SzE}z0u-vY0V^MlZYvQ<)T4*0qWw>K?_0BiuM3y5Ca=u0(JPrTMn>bJ zzkfvUZ#@vZNL;Xy&K0aFGiZbvOjsGLxOMUdi@=m>d%B#Ftv6A0e0X?RipS#~ssl7l z^I%Qjp=?Nb033!*kr11PO~=AT#mkV2p;^P0iw*W(2 V@UTBV9PR)B002ovPDHLkV1mw)_`U!D diff --git a/src/assets/images/FourthSelectedMarker.png b/src/assets/images/FourthSelectedMarker.png deleted file mode 100644 index 16fcbf5bd6d522fa060dc85642670c8de0e4f601..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139 zcmV-(1dRKMP) z6hRor|Faw>YNFeSuNclm3yo0{ZM0B~Hdf|>C>_{PA{3Ma2qh*$DHU`YB&QWL1Y!a< znt%Z*FyW9$cvu`JV8Y|Z@0;=NcJ_An_V#G}C!5=yo!$A(_n7(i1R_c%&&07;VM83) zkQHfER;ENEl|}@KupQN)nM@<3sHLkKYO+1vmZJMJ5Sb66ZgUVJRTM%FpQ(kAope@< zQp7;OAS`Q0B-T>FUHt}6#%*M_J85REC`SrLb_ZETcmpWYPe3B>`P8X9z{zVs<%xXT z);t|^!1fA!M(PrE8{OWw3II;k;6O~k?ek+7fJ@ClyulpYtu%pr9{`r$dW|+nAkPb% z4FDetTxka`HwO>y)(%PSm8Xc~-Ba}G!#vcG#{m$Ow#70uxRn9HaZ;-F*9}po1cAb`nk9&Pny^JAP6Z6m**gDPUqcF zsudJO;i^lPkY*vW_Zxxw(xQJEpp{!;mj52X!I;g0?H}4LPAv}T;5!!( z-0n1{sw@U!Q8gsr{i6Dsdym2L-{+x-y67O*!U*(#AP5VRe z%iV#yOYZyHq0g`P1ZNjpfoqPOs1zi{xb%|ms#0_wSM94~Ixf6i!UMPm;TLBi&OZu{ zlg%mfT8JV3(aW~PQ0@ksbMZAoi(zl|>%*OXPVvOtF0?SISQJCjwsCM|3E54IU-oeP z(4t?70i1#CsIrtLL?WFgYvi{%w#KKX;^`VztE28rN>de{t2c8+4Pv`}(?d;#jHL! z`bVi&Sm+I|7o6hRvlZO{YD970-Q-d7s~}}-)WA!;VP(HNjySS`-N$PH1MuM`SApvb zp+UIxmsI-8I1Wn^-J*V@%j;IaXQ0nVP$Y>-@nrqJ-(Ac1vBV~QU0ZD^dwj~cild33 zE>__4b!&t4lIS1|K!I57e~Ul}4MKrL{zR$D0R;aopt>TY26$Yx?hVM@#rK@*LDnyEyPe@M_oeEp$pMB|eXFcJYx z01d>=KQIF&1hU2ikYI-h8wLv_*igc1%i35rIeq`jjQzH z@S*cZF0G4{mX>ls5VV4V0@d&Lt2hkbX$BcSRT8wly`6S-bqUStk!F!OUlE9P8LZ|W zGnZ&r6+V38a`eC#M{lgVB8s9C3WXFHQb0RuXJ@Bo9$z*>ESqrS7+C1Q>KRY+Q%9|= z^avx?)@%e)J7M=(sPlzcu2%1w`u@-A*~&`z+g@H?UU2&KX$!PP+z^?lCXfK0eO>?F zRibA5GMC_d(75716WX@&c<{qZLqkIe_)BhXZkFLVHJ;kxE!q$=Ng-S(x3 zrT|c)>t6dqEsP7E{>ZVY+wJC&NQ5*rH1I$mz`MJ<320_y{w>FW1~~llhQ}!tKOnaW zM#bu;^0)TSE`F|3mSsmg9=CYCUJ(s^%v}62T#y0@CeXrf$sGct)@e`FY<*KzRXY%| z!(SF~Z-&R69@xxa#leb&I^W(`pA zAGV*b`N-jLL?Mn0m6erAt*xy|j3YQM7-5(_9Qk!IC6@KM7HV8Z$OA2~`)h=J1=={Y zIrV>i6FiNC9N!N?LC*fIRdCiF4{X{4!Au2N%Ju8lRj>`!9A~H%2)*zU=aW2$$5LuP z2*Ph(8`XdbJgQt^L?~*iSU(*$Y=LkuR#a55#>U1Gd&CBXh{m}_^O8UUKeZ8Z!87{b zf~Qk&)Q(9k7wU^!W+5Lq5&;aAfv2D&=(!0=pi$ENscbCJHkPbSwNLCDf4)_8x?tCM z{7lm{ee>oRBU3Ey>L83j32Pt_oW(d}W&zw0^Hv{am(ZWOYPiQ@v1p(P zwXm>IWsIQ~%nFU`5!1+Qq4yRjzfmGA%C?X_%>~gNP0uiK*_)fhjrgAjlgT8;1qBEw zSp0yS>VXQ0n6(3eR4dF2?_1&!Di3E{2zTzTBsmedn9@)tR4xTRKVyFejv@w{h(Sh; zL7frz`FvRP=mASKb2~8Ohy05?&pOY4EwX}jnTug82#*sBvY{`$ZxaxZK~567GE`k^ zad9!$6`ENfn^B8&baZId)z#|WK+U_HDCfu>Krr6B>)@5ur$AT&jzIz~$WEs-35o2M z!bZ1=w5k}NoQK z4GYr?%E!S^dn}Jh>fj`tFa=K3=)W;fI}q3oLWY6BFc_i)b|3=@1;RBR15dxJWRlPW zNNsH`8jZZ=toxn6f_s`|HPSH=;r~f}JAdq7y0qg;ODA{(#)KHyz_86`i{nv1gj6A4 zjH$M>6}njeF|4wnE5Z&eiA2J>xO~fuX^w@D+QgFk87-I&nb8Gh{xyv!qyE_M-RB0r z``Z^id=tLWHvsV<0R$32K*nMQy}>ZX@kykS(W~yhzCIxs3|hdwL`6|7kO3`5A`%Qu zniUcXz(Axxg`I@UP!cj`5-vh`_t4Pr$GZgOf?jt*3_$}fsH&=RfMzgkxnXx@@RS=* znakxW1(myT9J~zcNh^M5Xf$t*o@fHsvmGqT@D4gSILJV~6ol#DLu#hr1sbTIV+=qS zgt=PU`A_W{m=5z|Y_`qY6c!~QjAEd}J{q+t*hmHBZeyf2xLy1Y=^^|Yi}Y?u00000 LNkvXXu0mjf;e8PI diff --git a/src/assets/images/SecondSelectedMarker.png b/src/assets/images/SecondSelectedMarker.png deleted file mode 100644 index d236dc1260312172139cb6c9f194f789eab563a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1162 zcmV;51acxXn zdNVYaieNYFNzg+wUXo*%7W!xD&g<`++1Y(FnfG>QwugSO%2eQNefFt>}4`JIV5F)FVu`DjXr)SZ{&AiQDnF2mI1I(YwZk`9p{CN%7yI!!F z!q!?-ed#1&)4;+-;KMWS&GWb;8o7G0Kr$laCmBcr5`oJW>O~3dacw-)waYMep zb?umVX?;&M2E2N>Jf~Ok1kP`cM}YX~l4$YsW8#%yR{I$eGy`%`KoijUo(4!{GP{=F z@do?FB)ksJnT|MjD)E6~pxyUx0}t;FpL;qN7qZ`Cs*PGtaMql#aKX7=Y~!8H?B*oS z?-)fzpjJ7@h#LQqhja35cyUM?zQ7z{TZrHybT$&;+_&ok`L6+-Ac+hVKH;OLyV-R7 zP907(uMZadEJ)t>o4`+^g@a}ilD_2-baFa;UxQME5)z^XGfpSpf)fk9*qLi?qLpB$-X&#^%r-mHj#7j9r4bxseJ^NEAh15xj z)4}lhMOjxAflMPZO1P!ixso_3LI0?l*t|&N|0*O%Ak_c~9P@k&?i}R^JVu+E2u&e9 zeHd5sSj_{lE@PkRhwI~VP`Xza%eHpS%qinNI*utC{_UKuSHLp*CRn2EF*|h4G27)aMIZBnR&KVoGX&Ww~RhDDE-)ph?bO zaaUFwXo57E83?7dn=u8)y6xpT-4NkoUd~>@<|ldZ^i=;rLC%qsFk@<=kOaG(&U4c8 z_sVP@B*OIknmFhQqYg0sX~O+x@#Z~b8eA(0g5^~bnDz2g1rm9y8+$4!8na#lZI_@* zP}p5>s*|>1&o;33w`z$OFJXLy&v)^uYl7z*+(<65;}8kO5l{B=P&E<+9f|ftdBgP~pb`lOkxB$AlPDlknZQ^i2>CyQH|xc5 c2s|@*0x(6Q_f8{pFaQ7m07*qoM6N<$f-XuSS^xk5 diff --git a/src/assets/images/ThirdMarker.png b/src/assets/images/ThirdMarker.png deleted file mode 100644 index a55fa7fc6959db032b9cb66d873de0ec2e307f4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1711 zcmV;g22lBlP)Zg;oa?K3PDD)MNpKw=|CgIJ1*n5aP#YBT}Gs6-7vG|?D&w3zTP0{$Y= zq=|+IDxeTc6h&-}fJ9mpLa`+k0ZXebZRx%r^YEPM%(5-*bi48;H#;*sbMJT0<2&a9 z{10fF#zx&kHV`NAE;AQmjHMPNB6L5RA4~$w>Q7?<&D?QqZ7rwYzP>&d3$a6gqtP5B;K0XXb8|B{0_>KJ3#0DYg$oz>`OOV=AlNoQmSCLc+UHh13WC@i zI@uJ=%gfV3p^!Ff)-34h>Cu{+ngCsW^ZoRXDUiOXUAr3W&IY&*P-C$_Ix6#@$jQlx z*zNYn;NW1qy1H6M5=y#Tba$9paNzM5?gYt^wFO3lI~)}=o6f(ks;V=QNRV4>nBJV+ zot`yjOlTOzT=C{_#E6_e-lS7S2Ahi|I6BP%r^+1giQf*(Jc1<=aq9F{(gQU`ilR6? z9*>095J_j!6;3BX56-T9)rUd2%8J03rFMAAEr7?MzQDm@OOXVtyyFWm69iB3`mN8Q zut`Wn!e1i6(e)`3f+54aZPAlUnP96OZ?Y|DfeMMkv9JQGdlIl~P)0Hg<|7dr4L4*f zBE0{@9gTt@P%Ow@U0n)hi<+_oSp}t+aY1?*EU*i;=lSk9tm{icKppnyp`fDw5*aIS zPhOR0;UhlWuowsggp!gHjsZHt9Sju>1)j~fny5XY!mlw^CqQmkk|XG@AnYEJVItV) zRCsAUm&+xfTR2*RnZZfU)QHu;3^E1h)>(=Oq{oJc^LJaEVY zy9Sf`xF&0`3A89sEYKcT^&L|%(s;YTHX=4Cb;pA;aQ%$UW>e$wIHf2N(Xc-; zo1WpAK;eLnn)!c$qWnDGL|gl1Ov&LaAZw675h-#9r7p$Cc!-?%@o+MkB$hH-K_)_| zo~aL**&||x2wht~UScaLIRX}-h09U2$Q86OrL7gzp&Ms9?)AScNm3YNf+}hl`;2I3 zXD6kU{xLVJ83m{O?Bbt5PFlK!7CshH;2@^vL<9)ew{LtG2_(=03A|096=ZAy6)mlT znN?KVw{M?XP*9+RzCW-AGvzAW21L)ce9*tQ;RPC#hMYpE-UQ!`=e8)Oi8x1v=EVzfoXu4sTdnd z?5!6s4K-|kNQ;C&he?9cF?ev#8YHkAcOM}FIHKt8I9fu+)YKcA^s~xng&_%7vB1dP z@74FU&n_?uNPhJ^U_JItgMXs zNeNvmj@9C4Y>6@6V>qd98I)g!V#6@s_3zO-47ET-7pPR2X3UtO(s>j&pg{&_(Tqr# zs%pj*m0;?|sPIuQqE}%UJ_s8No2U2e55pOPLFSgU#DBIZ5geAY*-HQb002ovPDHLk FV1l%A8~XqN diff --git a/src/assets/images/ThirdSelectedMarker.png b/src/assets/images/ThirdSelectedMarker.png deleted file mode 100644 index bdfe7cb3f48c4b5afc1ba425f8dbb826240e8c9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1254 zcmV={e?XO- z%O#g2uBylj5>Tn4b(i(JoC=;KJ)Gh%81EYV=PCx zf}nOmQLes6eXd&+b;J2VOW+^T*p(GG`A=MhVgx$Y#&Z5bF zLBrPRT8cs^vc%$6(OK$>#0RzKB_+jLaL-3=L7%^F)6{T|UbCWivD#F0 z>**2Q-ff3WrYc+GgI}C&HxLzp*^xdb5I=bkh{(*phi4+g;$GeyADE9Mad~IIW)i@p zKfjaL;m?Yn{y*Z#w1Um^+v5Yv2C)t%cUXi00+o0Bdm;dQ`(_{A;B5?G0mAo@=y-ti zWx2^`(!+3qms}gPd|QH~ zU=r4QW~b43J^BDM!m8ksSRn`|8Cvi@Psbz_XN6D(iSB&?8RB75r=UuFW;kScn+f;| z5v;6Rd)~U}=>B&&yg#xtg46|G1ol1+xVQYvY}l3YtHDJ0dAO>9W--r|m?dtTt@jd0%#L)F`^WP( zee53S)C4I_z=k13D;q?&n?@uAZQx=ZmtL;des^D<=5YuR`XA1B4Cw4b!6jC00^9IfM`Wqi(VE_2m$k|npE zwi6Gew7|m5F$IZ=R{(1g8^w{jl(gb?Ks3I3co@4aX>fP1%~5C>1XNvGbW(4gBs8Ky zhBn}Wo+I`GWX|`Gj)KiA=4*hz#(dBy3rp9SCxFnB1Q!L=8z}DraJjTAnhic{t4=uU ztkM;;4f}{Rgs8gJ3099Nh7cgOgsZ`}Gs`R0o)nrYzowKZQ3$Sc)%B5M>C@Kt-oYnn zm5m5#Xr3uPNG@UU0+~p}5XnR!Gl>u)nF;ia_jmT^@J#~_ORqX!0ETQ7lW$Q* QWdHyG07*qoM6N<$g6I}X82|tP diff --git a/src/components/Plan/TripMap.tsx b/src/components/Plan/TripMap.tsx index 7c167103..4c91934c 100644 --- a/src/components/Plan/TripMap.tsx +++ b/src/components/Plan/TripMap.tsx @@ -1,16 +1,7 @@ import { Paths } from '@/@types/service'; import { useEffect, useRef, useState } from 'react'; import { Map, MapMarker, Polyline, useKakaoLoader } from 'react-kakao-maps-sdk'; -import FirstMarker from '@/assets/images/FirstMarker.png'; -import FirstSelectedMarker from '@/assets/images/FirstSelectedMarker.png'; -import SecondMarker from '@/assets/images/SecondMarker.png'; -import ThirdMarker from '@/assets/images/ThirdMarker.png'; -import FourthMarker from '@/assets/images/FourthMarker.png'; -import FifthMarker from '@/assets/images/FifthMarker.png'; -import SecondSelectedMarker from '@/assets/images/SecondSelectedMarker.png'; -import ThirdSelectedMarker from '@/assets/images/ThirdSelectedMarker.png'; -import FourthSelectedMarker from '@/assets/images/FourthSelectedMarker.png'; -import FifthSelectedMarker from '@/assets/images/FifthSelectedMarker.png'; +import { getColor } from '@utils/getColor'; const VITE_KAKAO_MAP_API_KEY = import.meta.env.VITE_KAKAO_MAP_API_KEY; @@ -104,30 +95,38 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { setSelectedMarker(index); }; - // 각 마커에 대한 이미지를 렌더링하는 함수 - const renderMarkerImage = (index: number, isSelected: boolean) => { - let svgComponent; - switch (index % 5) { - case 0: - svgComponent = isSelected ? FirstSelectedMarker : FirstMarker; - break; - case 1: - svgComponent = isSelected ? SecondSelectedMarker : SecondMarker; - break; - case 2: - svgComponent = isSelected ? ThirdSelectedMarker : ThirdMarker; - break; - case 3: - svgComponent = isSelected ? FourthSelectedMarker : FourthMarker; - break; - case 4: - svgComponent = isSelected ? FifthSelectedMarker : FifthMarker; - break; - default: - // 기본 마커 - return 'default_marker_image_url'; + // SVG 문자열을 Data URI로 변환하는 함수 + const getSequenceIconUrl = (number: number) => { + if (selectedMarker === number + 1) { + return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent( + SequenceMarker(number), + )}`; } - return svgComponent; + const svgString = encodeURIComponent(` + + + ${number} + + `); + return `data:image/svg+xml;charset=UTF-8,${svgString}`; + }; + + const SequenceMarker = (number: number) => { + const fillColor = getColor(number); + + return ` + + + + + ${number} + + + + + + + `; }; return ( @@ -136,39 +135,42 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { key={VITE_KAKAO_MAP_API_KEY} center={centerPosition} style={MapStyle} - level={10} + level={4} className="relative object-fill" ref={mapRef}> {paths.map((path, index) => ( -
+
handleMarkerClick(index)} - image={{ - src: renderMarkerImage(index, selectedMarker === index), - size: { - width: 33, - height: 33, - }, - }} - /> - handleMarkerClick(index)} + onClick={() => handleMarkerClick(path.toSeqNum)} image={{ - src: renderMarkerImage(index, selectedMarker === index), + src: getSequenceIconUrl(path.toSeqNum - 1), size: { - width: 33, - height: 33, + width: 24, + height: 24, }, }} /> + {/* 마지막 항목인 경우, 목적지 위치에 마커 추가 */} + {index === paths.length - 1 && ( + handleMarkerClick(path.toSeqNum + 1)} // 마지막 seqNum을 위한 +1 + image={{ + src: getSequenceIconUrl(path.toSeqNum), + size: { + width: 24, + height: 24, + }, + }} + /> + )} = ({ size = 21 }) => { return ( = ({ size = 21 }) => { = ({ size = 21 }) => { ); }; - export const ThumbsUp: React.FC = ({ size = 16, fill = '#1E1E1E', @@ -1589,6 +1589,8 @@ export const SequenceIcon: React.FC = ({ className, number, }) => { + const currentColor = getColor(number || 0); + return ( = ({ preserveAspectRatio="none"> {number !== undefined && ( = ({ dominantBaseline="middle" textAnchor="middle" fontSize="small" + fontWeight="bold" fill="white"> {number} @@ -1674,35 +1677,3 @@ export const PaperIcon: React.FC = ({}) => { ); }; - -export const PlanColorIcon = () => { - return ( - - - - - - - ); -}; diff --git a/src/utils/getColor.ts b/src/utils/getColor.ts new file mode 100644 index 00000000..2fbed7ef --- /dev/null +++ b/src/utils/getColor.ts @@ -0,0 +1,7 @@ +// 번호에 따른 색상을 반환하는 함수 +export const getColor = (num: number) => { + const colors = ['#FF2167', '#7932FF', '#29DDF6', '#FFAC16', '#16E7A9']; + + // 색상 배열에서 번호에 해당하는 색상을 반환 (숫자가 6 이상일 경우에는 색상 순서 반복) + return colors[(num - 1) % colors.length]; +}; From 788c9e1595820978692a0a5adab5d36156e458d3 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 20 Jan 2024 03:48:33 +0900 Subject: [PATCH 40/62] =?UTF-8?q?Chore:=20=EB=B9=8C=EB=93=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanSectionTop.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 5f99f5d4..114ee5a5 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -13,7 +13,6 @@ import { dayState, dateState } from '@recoil/plan'; import { tripIdState, memberIdState } from '@recoil/socket'; import { calculateDayAndDate } from '@utils/utils'; import { TripSchedule } from '@components/Trip/TripSchedule'; -import { getItem } from '@utils/localStorageFun'; const PlanSectionTop = () => { const navigate = useNavigate(); From 0080ff78ebfcf16fd85740656ab15c37281910e8 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 04:12:53 +0900 Subject: [PATCH 41/62] =?UTF-8?q?Feat:=20=EC=B0=B8=EC=97=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Share/IsEditableModal.tsx | 69 ++++++++++++++++++++++++ src/components/Trip/TripSectionTop.tsx | 12 ++++- src/components/common/icons/Icons.tsx | 50 +++++++++++++++++ src/pages/share/shareCode.page.tsx | 8 +-- 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/components/Share/IsEditableModal.tsx diff --git a/src/components/Share/IsEditableModal.tsx b/src/components/Share/IsEditableModal.tsx new file mode 100644 index 00000000..31dccb96 --- /dev/null +++ b/src/components/Share/IsEditableModal.tsx @@ -0,0 +1,69 @@ +import * as Dialog from '@radix-ui/react-dialog'; +import { EditStarIcon } from '@components/common/icons/Icons'; +import Alert from '@components/common/alert/Alert'; +import { useNavigate } from 'react-router-dom'; +import { getItem } from '@utils/localStorageFun'; + +interface Props { + isEditable: boolean; + setIsEditable: React.Dispatch>; +} + +const IsEditableModal = ({ isEditable, setIsEditable }: Props) => { + const navigate = useNavigate(); + const isLogin = getItem('accessToken'); + + const handleConfirm = () => { + navigate('/login'); + }; + + return ( + + + + + + + + + 편집 참여 코드를 입력하시면 +
+ 여행 계획을 함께 편집할 수 있어요! + + + + + {isLogin ? ( + + ) : ( + + 편집 참여 코드 입력을 위해 로그인이 필요해요. +
+ 로그인하시겠어요? + + } + onConfirm={handleConfirm}> + +
+ )} + + + + + + + ); +}; + +export default IsEditableModal; diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index 5c124851..d1388108 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -6,15 +6,25 @@ import { useNavigate } from 'react-router-dom'; import PlanTripButton from './PlanTripButton'; import { LikedToursList } from './LikedToursList'; import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; +import { useEffect, useState } from 'react'; +import IsEditableModal from '@components/Share/IsEditableModal'; const TripSectionTop = () => { const navigate = useNavigate(); const { tripAuthority } = useGetTripsAuthority(); + const [isEditable, setIsEditable] = useState(false); - console.log(tripAuthority); + useEffect(() => { + if (tripAuthority !== null) { + if (tripAuthority !== 'WRITE') { + setIsEditable(true); + } + } + }, [tripAuthority]); return (
+ { diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index ab793d75..a86f092a 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1562,6 +1562,56 @@ export const OrangeIcon: React.FC = ({ size = 20, className }) => { ); }; +export const EditStarIcon = () => { + return ( + + + + + + + + + + + + + ); +}; + export const GreenIcon: React.FC = ({ size = 20, className }) => { return ( { useEffect(() => { if (tripAuthority === 'WRITE' && TripId) { alert('이미 편집 가능한 여정입니다.'); - navigate(`/trip/${TripId}`); + navigate(`/trip/${TripId}`, { replace: true }); } }, [tripAuthority, TripId]); @@ -25,8 +25,10 @@ const shareCode = () => { } if (changeValue.length === 5 && TripId) { try { - const res = await postTripsjoin(TripId, changeValue); - console.log(res); + const { data } = await postTripsjoin(TripId, changeValue); + if (data.status === 200) { + navigate(`/trip/${TripId}`, { replace: true }); + } } catch (err) { setShowError(true); setInputCode(''); From 0008df4cc0c45becfcb7969aa713524de79e90e5 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 04:33:39 +0900 Subject: [PATCH 42/62] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=9B=84=20=EC=BD=94=EB=93=9C=20=EC=9E=85=EB=A0=A5=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Auth/Login/LoginForm.tsx | 10 ++++++++-- src/components/Plan/PlanSectionTop.tsx | 1 - src/components/Share/IsEditableModal.tsx | 9 ++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/Auth/Login/LoginForm.tsx b/src/components/Auth/Login/LoginForm.tsx index db12f7bc..d1e88621 100644 --- a/src/components/Auth/Login/LoginForm.tsx +++ b/src/components/Auth/Login/LoginForm.tsx @@ -1,7 +1,7 @@ import type { AuthRequest } from '@/@types/auth.types'; import { SubmitHandler, useForm } from 'react-hook-form'; import { postEmailLogin } from '@api/auth'; -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { AxiosError } from 'axios'; import { useState } from 'react'; import SubmitBtn from '@components/common/button/SubmitBtn'; @@ -26,6 +26,8 @@ const LoginForm = () => { }); const navigate = useNavigate(); + const { state } = useLocation(); + // const [userInfo, setUserInfo] = useRecoilState(UserInfoState); const onLoginSubmit: SubmitHandler = async (data) => { @@ -38,7 +40,11 @@ const LoginForm = () => { if (res.data.status === 200) { setItem('accessToken', res.data.data.tokenInfo.accessToken); // setUserInfo(res.data.data.memberDto); - navigate('/'); + if (state) { + navigate(`${state.prevPath}/code`); + } else { + navigate('/'); + } } } catch (err) { if (err instanceof AxiosError) { diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 5f99f5d4..114ee5a5 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -13,7 +13,6 @@ import { dayState, dateState } from '@recoil/plan'; import { tripIdState, memberIdState } from '@recoil/socket'; import { calculateDayAndDate } from '@utils/utils'; import { TripSchedule } from '@components/Trip/TripSchedule'; -import { getItem } from '@utils/localStorageFun'; const PlanSectionTop = () => { const navigate = useNavigate(); diff --git a/src/components/Share/IsEditableModal.tsx b/src/components/Share/IsEditableModal.tsx index 31dccb96..ee917224 100644 --- a/src/components/Share/IsEditableModal.tsx +++ b/src/components/Share/IsEditableModal.tsx @@ -1,7 +1,7 @@ import * as Dialog from '@radix-ui/react-dialog'; import { EditStarIcon } from '@components/common/icons/Icons'; import Alert from '@components/common/alert/Alert'; -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { getItem } from '@utils/localStorageFun'; interface Props { @@ -11,19 +11,18 @@ interface Props { const IsEditableModal = ({ isEditable, setIsEditable }: Props) => { const navigate = useNavigate(); + const { pathname } = useLocation(); + const isLogin = getItem('accessToken'); const handleConfirm = () => { - navigate('/login'); + navigate('/login', { state: { prevPath: pathname } }); }; return ( - - - 편집 참여 코드를 입력하시면 From a85edc758713cbc22c6323d8147a9776339edaa3 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 06:18:28 +0900 Subject: [PATCH 43/62] =?UTF-8?q?Feat:=20=EB=AA=A8=EB=8B=AC=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Share/CodeInput.tsx | 39 ++++++++++++++++++ src/components/Trip/EditCodeModal.tsx | 59 +++++++++++++++++++++++++++ src/components/Trip/TripSchedule.tsx | 5 +-- src/components/common/alert/Alert.tsx | 14 ++++--- 4 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 src/components/Share/CodeInput.tsx create mode 100644 src/components/Trip/EditCodeModal.tsx diff --git a/src/components/Share/CodeInput.tsx b/src/components/Share/CodeInput.tsx new file mode 100644 index 00000000..3fca6375 --- /dev/null +++ b/src/components/Share/CodeInput.tsx @@ -0,0 +1,39 @@ +interface Props { + inputCode: string; + setInputCode: React.Dispatch>; + showError: boolean; +} + +const CodeInput = ({ inputCode, setInputCode, showError }: Props) => { + const onCodeChange = async (e: React.ChangeEvent) => { + const changeValue = e.target.value; + if (changeValue.length <= 5) { + setInputCode(e.target.value); + } + }; + return ( +
+
+ +
+ {showError && ( +
+ 편집 참여 코드를 다시 한번 확인해주세요. +
+ )} +
+ ); +}; + +export default CodeInput; diff --git a/src/components/Trip/EditCodeModal.tsx b/src/components/Trip/EditCodeModal.tsx new file mode 100644 index 00000000..09609bfb --- /dev/null +++ b/src/components/Trip/EditCodeModal.tsx @@ -0,0 +1,59 @@ +import { postTripsjoin } from '@api/trips'; +import CodeInput from '@components/Share/CodeInput'; +import Alert from '@components/common/alert/Alert'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; +import { useState } from 'react'; +import { useParams } from 'react-router-dom'; + +const EditCodeModal = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + const [inputCode, setInputCode] = useState(''); + const [showError, setShowError] = useState(false); + + const { id: tripId } = useParams(); + const { tripAuthority } = useGetTripsAuthority(); + + const handleConfirm = async () => { + if (tripId) { + try { + const { data } = await postTripsjoin(Number(tripId), inputCode); + if (data.status === 200) { + setIsModalOpen(false); + } + } catch (err) { + setShowError(true); + setInputCode(''); + console.error('참여 코드 요청 중 에러 발생', err); + } + } + }; + + return ( + <> + {tripAuthority === 'WRITE' ? ( + + ) : ( + + } + isOpen={isModalOpen} + setIsOpen={setIsModalOpen} + onConfirm={handleConfirm}> + + + )} + + ); +}; + +export default EditCodeModal; diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index ad55e20e..9d6ea0cd 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -1,4 +1,5 @@ import { UserIcon } from '@components/common/icons/Icons'; +import EditCodeModal from './EditCodeModal'; export const TripSchedule = () => { return ( @@ -12,9 +13,7 @@ export const TripSchedule = () => { 5
- +
23.12.23 - 23.12.25 diff --git a/src/components/common/alert/Alert.tsx b/src/components/common/alert/Alert.tsx index df7f1dd1..dbb26a3f 100644 --- a/src/components/common/alert/Alert.tsx +++ b/src/components/common/alert/Alert.tsx @@ -3,13 +3,15 @@ import * as Dialog from '@radix-ui/react-dialog'; interface AlertProps { title: string; - message: ReactNode; + message?: ReactNode; onConfirm: (() => void) | ((e: React.MouseEvent) => void); onCancel?: (() => void) | ((e: React.MouseEvent) => void); children: ReactNode; content?: ReactNode; closeOnConfirm?: boolean; isCheck?: number | null; + isOpen?: boolean; + setIsOpen?: React.Dispatch>; } const Alert: FC = ({ @@ -21,8 +23,10 @@ const Alert: FC = ({ content, closeOnConfirm = false, isCheck = true, + isOpen, + setIsOpen, }) => ( - + {children} @@ -31,10 +35,10 @@ const Alert: FC = ({ + } fixed left-[50%] top-[50%] z-[130] flex min-h-[192px] w-[309px] translate-x-[-50%] translate-y-[-50%] flex-col items-center justify-center rounded-2xl bg-white px-[14px] shadow-lg focus:outline-none`}>

= ({ From 19fd1d6228dcf1275dbce28c15d7f35f06eea6e3 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 06:28:07 +0900 Subject: [PATCH 44/62] =?UTF-8?q?Refactor:=20=EA=B3=B5=EC=9C=A0=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanSectionTop.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 114ee5a5..99be9d1f 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -51,10 +51,13 @@ const PlanSectionTop = () => {

{ navigate(-1); }} + showShare={true} + shareHandler={() => { + navigate(`/trip/${tripId}/share`); + }} /> From 191b514634ec3e4f180a76aadc510188234355cf Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Sat, 20 Jan 2024 06:32:48 +0900 Subject: [PATCH 45/62] =?UTF-8?q?Refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=ED=9B=84=20url=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Auth/Login/LoginForm.tsx | 2 +- src/components/Share/IsEditableModal.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Auth/Login/LoginForm.tsx b/src/components/Auth/Login/LoginForm.tsx index d1e88621..0491d686 100644 --- a/src/components/Auth/Login/LoginForm.tsx +++ b/src/components/Auth/Login/LoginForm.tsx @@ -41,7 +41,7 @@ const LoginForm = () => { setItem('accessToken', res.data.data.tokenInfo.accessToken); // setUserInfo(res.data.data.memberDto); if (state) { - navigate(`${state.prevPath}/code`); + navigate(state.prevPath); } else { navigate('/'); } diff --git a/src/components/Share/IsEditableModal.tsx b/src/components/Share/IsEditableModal.tsx index ee917224..1465ff79 100644 --- a/src/components/Share/IsEditableModal.tsx +++ b/src/components/Share/IsEditableModal.tsx @@ -16,7 +16,7 @@ const IsEditableModal = ({ isEditable, setIsEditable }: Props) => { const isLogin = getItem('accessToken'); const handleConfirm = () => { - navigate('/login', { state: { prevPath: pathname } }); + navigate('/login', { state: { prevPath: `${pathname}/code` } }); }; return ( From bdaab020395444b142603d0525c3d16519fb43f1 Mon Sep 17 00:00:00 2001 From: sue Date: Sat, 20 Jan 2024 18:03:15 +0900 Subject: [PATCH 46/62] =?UTF-8?q?Feat:=20=EB=A7=B5=EB=A7=88=EC=BB=A4=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/TripMap.tsx | 139 ++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 50 deletions(-) diff --git a/src/components/Plan/TripMap.tsx b/src/components/Plan/TripMap.tsx index 4c91934c..94dac763 100644 --- a/src/components/Plan/TripMap.tsx +++ b/src/components/Plan/TripMap.tsx @@ -10,13 +10,15 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { const latitude = firstPath?.fromLatitude; const longitude = firstPath?.fromLongitude; - // Kakao Maps SDK 로드 상태 + const mapRef = useRef(null); + const [selectedMarker, setSelectedMarker] = useState(null); + + const defaultPosition = { lat: Number(latitude), lng: Number(longitude) }; + const [_] = useKakaoLoader({ appkey: VITE_KAKAO_MAP_API_KEY, }); - const defaultPosition = { lat: Number(latitude), lng: Number(longitude) }; - const getCenterPosition = () => { if (paths.length === 0) { return defaultPosition; @@ -59,8 +61,6 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { }); } - const mapRef = useRef(null); - // 지도 범위 재설정 함수 const setBounds = () => { if (mapRef.current) { @@ -87,9 +87,6 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { setBounds(); }, [paths]); - // 선택된 마커의 인덱스를 추적하기 위한 상태 - const [selectedMarker, setSelectedMarker] = useState(null); - // 마커를 클릭할 때 호출되는 함수 const handleMarkerClick = (index: number) => { setSelectedMarker(index); @@ -97,36 +94,90 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { // SVG 문자열을 Data URI로 변환하는 함수 const getSequenceIconUrl = (number: number) => { + let svgString; + let width, height; + if (selectedMarker === number + 1) { - return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent( - SequenceMarker(number), - )}`; + width = 32; + height = 39; + svgString = encodeURIComponent(` + + + + + ${number} + + + + + + + + + + + + + + + `); + } else { + width = 24; + height = 24; + svgString = encodeURIComponent(` + + + ${number} + + `); } - const svgString = encodeURIComponent(` - - - ${number} - - `); - return `data:image/svg+xml;charset=UTF-8,${svgString}`; - }; - const SequenceMarker = (number: number) => { - const fillColor = getColor(number); - - return ` - - - - - ${number} - - - - - - - `; + return { + src: `data:image/svg+xml;charset=UTF-8,${svgString}`, + size: { width, height }, + }; }; return ( @@ -146,13 +197,7 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { lng: Number(path.fromLongitude), }} onClick={() => handleMarkerClick(path.toSeqNum)} - image={{ - src: getSequenceIconUrl(path.toSeqNum - 1), - size: { - width: 24, - height: 24, - }, - }} + image={getSequenceIconUrl(path.toSeqNum - 1)} /> {/* 마지막 항목인 경우, 목적지 위치에 마커 추가 */} {index === paths.length - 1 && ( @@ -161,14 +206,8 @@ const TripMap = ({ paths }: { paths: Paths[] }) => { lat: Number(path.toLatitude), lng: Number(path.toLongitude), }} - onClick={() => handleMarkerClick(path.toSeqNum + 1)} // 마지막 seqNum을 위한 +1 - image={{ - src: getSequenceIconUrl(path.toSeqNum), - size: { - width: 24, - height: 24, - }, - }} + onClick={() => handleMarkerClick(path.toSeqNum + 1)} + image={getSequenceIconUrl(path.toSeqNum)} /> )} Date: Sat, 20 Jan 2024 18:21:27 +0900 Subject: [PATCH 47/62] =?UTF-8?q?feat:=20=EC=9A=B0=EB=A6=AC=EC=9D=98=20?= =?UTF-8?q?=EA=B4=80=EC=8B=AC=EB=AA=A9=EB=A1=9D=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/trips.ts | 42 ++++-- .../common/button/ListSelectBtn.tsx | 8 +- src/pages/plan/OurLikedList.tsx | 124 ++++++++---------- src/pages/plan/addPlace/AddtoListBtn.tsx | 29 ++-- src/pages/plan/addPlace/MyLiked.tsx | 11 +- src/pages/plan/addPlace/MyLikedList.tsx | 2 +- src/pages/plan/addPlace/MyLikedListItem.tsx | 7 +- src/pages/plan/addPlace/PlanAddPlace.page.tsx | 6 +- .../plan/addPlace/ResultCategoryPlan.tsx | 7 +- src/pages/plan/addPlace/ResultItem.tsx | 6 +- src/pages/plan/addPlace/SearchResult.tsx | 7 +- src/pages/search/search.page.tsx | 4 +- src/pages/trip/AddOurList.tsx | 2 +- src/router/routerLayout.tsx | 4 +- src/utils/getTripIdFromUrl.ts | 7 + 15 files changed, 145 insertions(+), 121 deletions(-) create mode 100644 src/utils/getTripIdFromUrl.ts diff --git a/src/api/trips.ts b/src/api/trips.ts index be019a7f..b9aac400 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -10,8 +10,16 @@ export const getTrips = async (tripId: number) => { }; // 여정 기본정보 수정 -export const putTrips = async (tripId: number, tripsData: TripRequest) => { - const res = await client.put(`trips/${tripId}`, tripsData); +export const putTrips = async ( + tripId: number, + tourItemId: number, + visitDate: string, +) => { + const requestBody = { + tourItemId: tourItemId, + visitDate: visitDate, + }; + const res = await authClient.post(`trips/${tripId}`, requestBody); return res; }; @@ -33,16 +41,26 @@ export const postTrips = async (tripsData: TripRequest) => { }; // 우리의 관심목록 조회 -export const getTripsLike = async ( - tripId: number, - category: number, - page: number, - size: number, -) => { - const res = await client.get( - `trips/${tripId}/tripLikedTours?category=${category}&page=${page}$size=${size}`, - ); - return res; +export const getTripsLike = async (options: { + tripId: number; + category?: string; + page?: number; + size?: number; +}) => { + const { tripId, category, page = 0, size } = options; + + let query = `trips/${tripId}/tripLikedTours?`; + + if (category) { + query += `&category=${category}`; + } + query += `&page=${page}`; + + if (size) { + query += `&size=${size}`; + } + const res = await authClient.get(query); + return res.data; }; // 우리의 관심 목록 등록 diff --git a/src/components/common/button/ListSelectBtn.tsx b/src/components/common/button/ListSelectBtn.tsx index 4328e6d2..e4f439df 100644 --- a/src/components/common/button/ListSelectBtn.tsx +++ b/src/components/common/button/ListSelectBtn.tsx @@ -9,8 +9,9 @@ interface ListSelectBtnProps { export const ListSelectBtn = ({ children, onClick }: ListSelectBtnProps) => { const [isActive, setIsActive] = useState(false); - const handleClick = () => { + const handleClick = (e: React.MouseEvent) => { setIsActive(!isActive); + e.stopPropagation(); if (onClick) { onClick(); } @@ -36,15 +37,16 @@ interface ListCheckBtnProps { export const ListCheckBtn = ({ onClick }: ListCheckBtnProps) => { const [isActive, setIsActive] = useState(false); - const handleClick = () => { + const handleClick = (e: React.MouseEvent) => { setIsActive(!isActive); + e.stopPropagation(); if (onClick) { onClick(); } }; return ( -
+
+
- 23.12.23 - 23.12.25 + + {startDate?.substring(2).replace(/-/g, '.') || ''} -{' '} + {endDate?.substring(5).replace(/-/g, '.') || ''} + ); }; diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index 59ef58eb..82e03c8e 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -5,13 +5,9 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import PlanTripButton from './PlanTripButton'; import { LikedToursList } from './LikedToursList'; -import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; const TripSectionTop = () => { const navigate = useNavigate(); - const { tripAuthority } = useGetTripsAuthority(); - - console.log(tripAuthority); return (
diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 1c66fb80..5bc316d1 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1314,14 +1314,14 @@ export const PlanColorIcon: React.FC = ({ size = 21 }) => { { + const { id } = useParams(); + + const defaultReturn = { + tripName: null, + startDate: null, + endDate: null, + numberOfPeople: null, + }; + + if (!id) { + return defaultReturn; + } + + const { data, isLoading, isError } = useQuery({ + queryKey: ['getTrips', id], + queryFn: () => getTrips(id), + enabled: !!id, + staleTime: 60000, + }); + + const tripName = data?.data.data.tripName; + const startDate = data?.data.data.startDate; + const endDate = data?.data.data.endDate; + const numberOfPeople = data?.data.data.numberOfPeople; + + if (isLoading || isError) { + return defaultReturn; + } + + return { tripName, startDate, endDate, numberOfPeople }; +}; diff --git a/src/hooks/useGetTripsAuthority.ts b/src/hooks/useGetTripsAuthority.ts index efef5695..1dd72859 100644 --- a/src/hooks/useGetTripsAuthority.ts +++ b/src/hooks/useGetTripsAuthority.ts @@ -6,7 +6,7 @@ import { useParams } from 'react-router-dom'; type useGetTripsAuthorityReturn = { tripAuthority: string | null; memberId: number | null; - TripId: number | null; + tripId: string | null; }; export const useGetTripsAuthority = (): useGetTripsAuthorityReturn => { @@ -15,7 +15,7 @@ export const useGetTripsAuthority = (): useGetTripsAuthorityReturn => { const defaultReturn = { tripAuthority: null, memberId: null, - TripId: null, + tripId: null, }; if (!id) { @@ -25,15 +25,16 @@ export const useGetTripsAuthority = (): useGetTripsAuthorityReturn => { queryKey: ['getTripsAuthority', id], queryFn: () => getTripsAuthority(id), enabled: !!id, + staleTime: 60000, }); const tripAuthority = data?.data.data.tripAuthority; const memberId = data?.data.data.memberId; - const TripId = data?.data.data.TripId; + const tripId = data?.data.data.TripId; if (isLoading || isError) { return defaultReturn; } - return { tripAuthority, memberId, TripId }; + return { tripAuthority, memberId, tripId }; }; diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 6f07b0ca..37b7831a 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -16,6 +16,9 @@ import { } from '@/@types/service'; import { createContext } from 'react'; import { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import { visitDateState } from '@recoil/socket'; export const socketContext = createContext({ tripInfo: null, @@ -23,16 +26,20 @@ export const socketContext = createContext({ tripPath: null, tripMember: null, tripBudget: null, + tripId: '', callBackPub: () => {}, }); -export const useSocket = (tripId: string, visitDate: string) => { +export const useSocket = () => { + const { id } = useParams(); + const tripId = id ?? ''; + const visitDate = useRecoilValue(visitDateState); + const [tripInfo, setTripInfo] = useState(null); const [tripItem, setTripItem] = useState(null); const [tripPath, setTripPath] = useState(null); const [tripMember, setTripMember] = useState(null); const [tripBudget, setTripBudget] = useState(null); - const [socketCallback, setSocketCallback] = useState<(() => void) | null>( null, ); @@ -41,7 +48,7 @@ export const useSocket = (tripId: string, visitDate: string) => { setSocketCallback(() => callback); }; - const socketConnect = () => { + const socketConnect = (tripId: string, visitDate: string) => { socketClient.onConnect = () => { subInfo(tripId, (res) => { if (res) { @@ -63,7 +70,6 @@ export const useSocket = (tripId: string, visitDate: string) => { subMember(tripId, (res) => { if (res) { - // console.log('subMemberRes', res); setTripMember(res); } }); @@ -83,13 +89,23 @@ export const useSocket = (tripId: string, visitDate: string) => { }; useEffect(() => { - socketConnect(); - console.log('소켓연결'); + if (tripId && visitDate) { + socketConnect(tripId, visitDate.visitDate); + console.log(visitDate); + } return () => { socketClient.deactivate(); }; }, [tripId, visitDate, socketCallback]); - return { tripInfo, tripItem, tripPath, tripMember, tripBudget, callBackPub }; + return { + tripInfo, + tripItem, + tripPath, + tripMember, + tripBudget, + tripId, + callBackPub, + }; }; diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts index ab7bb76b..fca451c7 100644 --- a/src/recoil/socket.ts +++ b/src/recoil/socket.ts @@ -2,15 +2,10 @@ import { atom } from 'recoil'; export const tripIdState = atom({ key: 'tripIdState', - default: '1', + default: '', }); export const visitDateState = atom<{ visitDate: string } | null>({ key: 'visitDateState', - default: { visitDate: '2024-01-03' }, -}); - -export const memberIdState = atom<{ token: number | null }>({ - key: 'memberIdState', - default: { token: null }, + default: { visitDate: '' }, }); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index e679617b..228c62b5 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -5,19 +5,11 @@ import { PlanAddPlace } from '@pages/plan/addPlace/PlanAddPlace.page'; import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; -import { useRecoilValue } from 'recoil'; -import { tripIdState, visitDateState } from '@recoil/socket'; import { AddOurList } from '@pages/trip/AddOurList'; const SocketRoutes = () => { - const tripId = useRecoilValue(tripIdState); - const visitDate = useRecoilValue(visitDateState); - if (!tripId || !visitDate) { - return
에러
; - } - return ( - + } /> } /> From 5017bcf152f3969e85ef2f3396d7147150f05eb0 Mon Sep 17 00:00:00 2001 From: Shim Jeong ah <35457850+joanShim@users.noreply.github.com> Date: Sun, 21 Jan 2024 00:04:13 +0900 Subject: [PATCH 50/62] =?UTF-8?q?Feat:=20=EC=97=AC=EC=A0=95=EA=B3=84?= =?UTF-8?q?=ED=9A=8D=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/tours.types.ts | 15 +++++ src/api/socket.ts | 4 +- src/api/trips.ts | 2 +- .../OurLiked.tsx} | 11 ++-- src/pages/plan/AddToTripPlan/OurLikedList.tsx | 62 +++++++++++++++++ .../plan/AddToTripPlan/OurLikedListItem.tsx | 66 +++++++++++++++++++ .../AddtoListBtn.tsx | 28 ++++++-- .../{addPlace => addToOurPlace}/MyLiked.tsx | 0 .../MyLikedList.tsx | 0 .../MyLikedListItem.tsx | 6 ++ .../PlanAddPlace.page.tsx | 4 +- .../ResultCategoryPlan.tsx | 0 .../ResultItem.tsx | 0 .../SearchResult.tsx | 0 .../{AddOurList.tsx => AddOurList.page.tsx} | 4 +- src/router/socketRouter.tsx | 4 +- 16 files changed, 185 insertions(+), 21 deletions(-) rename src/pages/plan/{OurLikedList.tsx => AddToTripPlan/OurLiked.tsx} (91%) create mode 100644 src/pages/plan/AddToTripPlan/OurLikedList.tsx create mode 100644 src/pages/plan/AddToTripPlan/OurLikedListItem.tsx rename src/pages/plan/{addPlace => addToOurPlace}/AddtoListBtn.tsx (50%) rename src/pages/plan/{addPlace => addToOurPlace}/MyLiked.tsx (100%) rename src/pages/plan/{addPlace => addToOurPlace}/MyLikedList.tsx (100%) rename src/pages/plan/{addPlace => addToOurPlace}/MyLikedListItem.tsx (95%) rename src/pages/plan/{addPlace => addToOurPlace}/PlanAddPlace.page.tsx (91%) rename src/pages/plan/{addPlace => addToOurPlace}/ResultCategoryPlan.tsx (100%) rename src/pages/plan/{addPlace => addToOurPlace}/ResultItem.tsx (100%) rename src/pages/plan/{addPlace => addToOurPlace}/SearchResult.tsx (100%) rename src/pages/trip/{AddOurList.tsx => AddOurList.page.tsx} (84%) diff --git a/src/@types/tours.types.ts b/src/@types/tours.types.ts index 2b722c6d..ccd95671 100644 --- a/src/@types/tours.types.ts +++ b/src/@types/tours.types.ts @@ -37,3 +37,18 @@ export interface TourType { longitude?: string; latitude?: string; } + +export interface LikedListType { + tripLikedItemId: number; + tourItemId: number; + contentTypeId: number; + title: string; + ratingAverage: number; + reviewCount: number; + smallThumbnailUrl: string; + tourAddress: string; + prefer: boolean; + notPrefer: boolean; + preferTotalCount: number; + notPreferTotalCount: number; +} diff --git a/src/api/socket.ts b/src/api/socket.ts index 000830cf..300d9037 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -79,6 +79,7 @@ export const pubAddTripItem = ( destination: `/pub/trips/${tripId}/addTripItems`, body: JSON.stringify(pubAddTripItem), }); + console.log(pubAddTripItem); }; // 여행 아이템 예상 가격 업데이트 이벤트 발생시 @@ -101,8 +102,6 @@ export const pubUpdateTripItem = ( destination: `/pub/trips/${tripId}/updateTripItemOrder`, body: JSON.stringify(pubUpdateTripItem), }); - - console.log('데이터', pubUpdateTripItem); }; // 여행 날짜별 교통 수단 변경 이벤트 발생시 (01/16 업데이트) @@ -136,7 +135,6 @@ export const pubDeleteItem = ( destination: `/pub/tripItems/${tripItemId}/deleteItem`, body: JSON.stringify(pubDeleteItem), }); - console.log(pubDeleteItem); }; // 멤버 여정 페이지로 입장 이벤트 발생시 diff --git a/src/api/trips.ts b/src/api/trips.ts index dc41f9e3..405dd43d 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -54,7 +54,7 @@ export const getTripsLike = async ( }; // 우리의 관심 목록 등록 -export const postTripsLike = async (tripId: number, tourItemIds: number[]) => { +export const postTripsLike = async (tripId: string, tourItemIds: number[]) => { const requestBody = { tourItemIds: tourItemIds, }; diff --git a/src/pages/plan/OurLikedList.tsx b/src/pages/plan/AddToTripPlan/OurLiked.tsx similarity index 91% rename from src/pages/plan/OurLikedList.tsx rename to src/pages/plan/AddToTripPlan/OurLiked.tsx index 907790ac..7b0dae46 100644 --- a/src/pages/plan/OurLikedList.tsx +++ b/src/pages/plan/AddToTripPlan/OurLiked.tsx @@ -3,12 +3,11 @@ import { useState } from 'react'; import { Spinner } from '@components/common/spinner/Spinner'; import { getTripsLike } from '@api/trips'; import { getTripIdFromUrl } from '@utils/getTripIdFromUrl'; - -import { MyLikedList } from './addPlace/MyLikedList'; import WishCategory from '@components/Wish/WishCategory'; -import AddToListButton from './addPlace/AddtoListBtn'; +import AddToListButton from '../addToOurPlace/AddtoListBtn'; +import { OurLikedList } from './OurLikedList'; -export const OurLikedList = () => { +export const OurLiked = () => { const [selectedContentTypeId, setSelectedContentTypeId] = useState< null | number >(null); @@ -60,10 +59,10 @@ export const OurLikedList = () => { {noResults ? (
- 나의 관심목록이 없습니다. + 우리의 관심목록이 없습니다.
) : ( - }; + fetchNextPage: () => void; + hasNextPage: boolean; + isLoading: boolean; + selectedContentTypeId: number | null; +} + +export const OurLikedList: React.FC = ({ + toursData, + fetchNextPage, + hasNextPage, + isLoading, + selectedContentTypeId, +}) => { + if (!toursData || toursData.pages.length === 0) { + return
데이터를 불러오는 중 오류가 발생했습니다.
; + } + + const filteredData = + selectedContentTypeId !== null + ? toursData.pages.map((group) => ({ + data: { + content: group.data.content.filter( + (item) => item.contentTypeId === selectedContentTypeId, + ), + }, + })) + : toursData.pages; + + return ( +
+ fetchNextPage()} + hasMore={hasNextPage} + loader={ +
+ +
+ }> +
+ {!isLoading && + filteredData.map((group) => ( + + {group?.data.content.map((wishList: LikedListType) => ( + + ))} + + ))} +
+
+
+ ); +}; diff --git a/src/pages/plan/AddToTripPlan/OurLikedListItem.tsx b/src/pages/plan/AddToTripPlan/OurLikedListItem.tsx new file mode 100644 index 00000000..19a20840 --- /dev/null +++ b/src/pages/plan/AddToTripPlan/OurLikedListItem.tsx @@ -0,0 +1,66 @@ +import { LikedListType } from '@/@types/tours.types'; +import { ListCheckBtn } from '@components/common/button/ListSelectBtn'; +import { StarIcon } from '@components/common/icons/Icons'; +import { selectedItemsState } from '@recoil/listItem'; +import { useRecoilState } from 'recoil'; +import { useNavigate } from 'react-router-dom'; +import { useEffect } from 'react'; + +interface WishItemProps { + wishList: LikedListType; +} + +export const OurLikedListItem: React.FC = ({ wishList }) => { + const { + tourItemId, + title, + ratingAverage, + reviewCount, + smallThumbnailUrl, + tourAddress, + } = wishList; + + const [selectedItems, setSelectedItems] = useRecoilState(selectedItemsState); + const navigate = useNavigate(); + + useEffect(() => { + setSelectedItems([]); + }, []); + + const handleSelect = () => { + if (selectedItems.includes(tourItemId)) { + setSelectedItems(selectedItems.filter((item) => item !== tourItemId)); + } else { + setSelectedItems([...selectedItems, tourItemId]); + } + }; + + return ( +
navigate(`/detail/${tourItemId}`)}> +
+ {title} +
+
+
{title}
+
+
+ +
+ + {ratingAverage.toFixed(1)}({reviewCount}) + + + {tourAddress ? tourAddress : '제공되는 주소가 없습니다.'} + +
+
+ +
+ ); +}; diff --git a/src/pages/plan/addPlace/AddtoListBtn.tsx b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx similarity index 50% rename from src/pages/plan/addPlace/AddtoListBtn.tsx rename to src/pages/plan/addToOurPlace/AddtoListBtn.tsx index 4b3bcb08..6fc1ff16 100644 --- a/src/pages/plan/addPlace/AddtoListBtn.tsx +++ b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx @@ -1,9 +1,13 @@ import { useRecoilValue } from 'recoil'; import { selectedItemsState } from '@recoil/listItem'; import { ButtonPrimary } from '@components/common/button/Button'; -import { postTripsLike, putTrips } from '@api/trips'; +import { postTripsLike } from '@api/trips'; import { getTripIdFromUrl } from '@utils/getTripIdFromUrl'; import { useNavigate } from 'react-router-dom'; +import { pubAddTripItem } from '@api/socket'; +import { useContext } from 'react'; +import { socketContext } from '@hooks/useSocket'; +import { visitDateState } from '@recoil/socket'; const AddToListButton = ({ apiType, @@ -11,20 +15,34 @@ const AddToListButton = ({ apiType: 'postTripsLike' | 'putTrips'; }) => { const selectedTourItemIds = useRecoilValue(selectedItemsState); - const VISIT_DATE = '2024-02-01'; + console.log('selectedTourItemIds', selectedTourItemIds); + const visitDate = useRecoilValue(visitDateState); + console.log('visitDate', visitDate); + const { callBackPub } = useContext(socketContext); const navigate = useNavigate(); const handleAddClick = async () => { - const tripId = getTripIdFromUrl(); + const tripId = getTripIdFromUrl().toString(); if (tripId) { try { let response; if (apiType === 'postTripsLike') { response = await postTripsLike(tripId, selectedTourItemIds); navigate(`/trip/${tripId}`); - } else if (apiType === 'putTrips' && selectedTourItemIds.length > 0) { - response = await putTrips(tripId, selectedTourItemIds[0], VISIT_DATE); + } else if (apiType === 'putTrips' && visitDate) { + const newTripItems = selectedTourItemIds.map((tourItemId) => ({ + tourItemId: tourItemId, + })); + + const pubAddTripItemData = { + visitDate: visitDate.visitDate, + newTripItems, + }; + + console.log('pubAddTripItemData', pubAddTripItemData); + callBackPub(() => pubAddTripItem(pubAddTripItemData, tripId)); + navigate(`/trip/${tripId}/plan`); } console.log('API response:', response); } catch (error) { diff --git a/src/pages/plan/addPlace/MyLiked.tsx b/src/pages/plan/addToOurPlace/MyLiked.tsx similarity index 100% rename from src/pages/plan/addPlace/MyLiked.tsx rename to src/pages/plan/addToOurPlace/MyLiked.tsx diff --git a/src/pages/plan/addPlace/MyLikedList.tsx b/src/pages/plan/addToOurPlace/MyLikedList.tsx similarity index 100% rename from src/pages/plan/addPlace/MyLikedList.tsx rename to src/pages/plan/addToOurPlace/MyLikedList.tsx diff --git a/src/pages/plan/addPlace/MyLikedListItem.tsx b/src/pages/plan/addToOurPlace/MyLikedListItem.tsx similarity index 95% rename from src/pages/plan/addPlace/MyLikedListItem.tsx rename to src/pages/plan/addToOurPlace/MyLikedListItem.tsx index 8e5fdf81..67628128 100644 --- a/src/pages/plan/addPlace/MyLikedListItem.tsx +++ b/src/pages/plan/addToOurPlace/MyLikedListItem.tsx @@ -4,6 +4,7 @@ import { StarIcon } from '@components/common/icons/Icons'; import { selectedItemsState } from '@recoil/listItem'; import { useRecoilState } from 'recoil'; import { useNavigate } from 'react-router-dom'; +import { useEffect } from 'react'; interface WishItemProps { wishList: TourType; @@ -21,6 +22,11 @@ export const MyLikedListItem: React.FC = ({ wishList }) => { const [selectedItems, setSelectedItems] = useRecoilState(selectedItemsState); const navigate = useNavigate(); + + useEffect(() => { + setSelectedItems([]); + }, []); + const handleSelect = () => { if (selectedItems.includes(id)) { setSelectedItems(selectedItems.filter((item) => item !== id)); diff --git a/src/pages/plan/addPlace/PlanAddPlace.page.tsx b/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx similarity index 91% rename from src/pages/plan/addPlace/PlanAddPlace.page.tsx rename to src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx index 303ad92c..4fcfa8bf 100644 --- a/src/pages/plan/addPlace/PlanAddPlace.page.tsx +++ b/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx @@ -2,7 +2,7 @@ import SearchInput from '@components/search/SearchInput'; import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import { SearchResultForPlan } from './SearchResult'; -import { OurLikedList } from '../OurLikedList'; +import { OurLiked } from '../AddToTripPlan/OurLiked'; export const PlanAddPlace = () => { const location = useLocation(); @@ -25,7 +25,7 @@ export const PlanAddPlace = () => { {searchWord ? ( ) : ( - + )}
); diff --git a/src/pages/plan/addPlace/ResultCategoryPlan.tsx b/src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx similarity index 100% rename from src/pages/plan/addPlace/ResultCategoryPlan.tsx rename to src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx diff --git a/src/pages/plan/addPlace/ResultItem.tsx b/src/pages/plan/addToOurPlace/ResultItem.tsx similarity index 100% rename from src/pages/plan/addPlace/ResultItem.tsx rename to src/pages/plan/addToOurPlace/ResultItem.tsx diff --git a/src/pages/plan/addPlace/SearchResult.tsx b/src/pages/plan/addToOurPlace/SearchResult.tsx similarity index 100% rename from src/pages/plan/addPlace/SearchResult.tsx rename to src/pages/plan/addToOurPlace/SearchResult.tsx diff --git a/src/pages/trip/AddOurList.tsx b/src/pages/trip/AddOurList.page.tsx similarity index 84% rename from src/pages/trip/AddOurList.tsx rename to src/pages/trip/AddOurList.page.tsx index 38da00c8..14ce38b8 100644 --- a/src/pages/trip/AddOurList.tsx +++ b/src/pages/trip/AddOurList.page.tsx @@ -1,6 +1,6 @@ import SearchInput from '@components/search/SearchInput'; -import { MyLiked } from '@pages/plan/addPlace/MyLiked'; -import { SearchResultForPlan } from '@pages/plan/addPlace/SearchResult'; +import { MyLiked } from '@pages/plan/addToOurPlace/MyLiked'; +import { SearchResultForPlan } from '@pages/plan/addToOurPlace/SearchResult'; import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index e679617b..b8bfc39b 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -1,13 +1,13 @@ import { Route, Routes } from 'react-router-dom'; import { useSocket, socketContext } from '@hooks/useSocket'; import PlanTrip from '@pages/plan/planTrip.page'; -import { PlanAddPlace } from '@pages/plan/addPlace/PlanAddPlace.page'; +import { PlanAddPlace } from '@pages/plan/addToOurPlace/PlanAddPlace.page'; import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; import { useRecoilValue } from 'recoil'; import { tripIdState, visitDateState } from '@recoil/socket'; -import { AddOurList } from '@pages/trip/AddOurList'; +import { AddOurList } from '@pages/trip/AddOurList.page'; const SocketRoutes = () => { const tripId = useRecoilValue(tripIdState); From 89b29cceabd3f5e7d92c29a2c9e5cafc5ff5cd00 Mon Sep 17 00:00:00 2001 From: sue Date: Sun, 21 Jan 2024 00:24:16 +0900 Subject: [PATCH 51/62] =?UTF-8?q?Fix:=20=ED=83=AD=20=ED=8A=B8=EB=A6=AC?= =?UTF-8?q?=EA=B1=B0=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/tab/Tab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/tab/Tab.tsx b/src/components/common/tab/Tab.tsx index f3a799c9..c75d14f2 100644 --- a/src/components/common/tab/Tab.tsx +++ b/src/components/common/tab/Tab.tsx @@ -37,7 +37,7 @@ const Tab = ({ lists, contents }: TabProps) => { key={index} className={`${ isDayTab ? 'caption1' : 'headline1 flex-1' - } flex min-w-[57px] cursor-pointer select-none items-center justify-center overflow-x-scroll border-b-2 border-solid border-gray2 py-[8px] leading-none text-gray4 outline-none data-[state=active]:border-b-2 data-[state=active]:border-solid data-[state=active]:border-black data-[state=active]:text-black`} + } flex min-w-[57px] cursor-pointer select-none items-center justify-center border-b-2 border-solid border-gray2 py-[8px] leading-none text-gray4 outline-none data-[state=active]:border-b-2 data-[state=active]:border-solid data-[state=active]:border-black data-[state=active]:text-black`} value={`tab${index}`}> {list} From f58e6291b9728e77a2cbedba2ddd0fc90ff1c80b Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 21 Jan 2024 11:08:07 +0900 Subject: [PATCH 52/62] =?UTF-8?q?Feat:=20=EC=83=81=EC=84=B8=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=9D=BC=EC=A0=95=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/trips.ts | 6 ++ .../DetailSectionTop/DetailAddSchedule.tsx | 78 ++++++++++++++----- src/components/common/icons/Icons.tsx | 4 +- src/hooks/useGetMyTrips.ts | 28 +++++++ src/utils/utils.ts | 19 +++-- 5 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 src/hooks/useGetMyTrips.ts diff --git a/src/api/trips.ts b/src/api/trips.ts index 675b6ee4..c2fdf166 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -91,3 +91,9 @@ export const getTripsAuthority = async (tripId: string) => { const res = await authClient.get(`trips/${tripId}/authority`); return res; }; + +// 나의 여정목록 조회 +export const getMyTrips = async () => { + const res = await authClient.get(`trips`); + return res; +}; diff --git a/src/components/DetailSectionTop/DetailAddSchedule.tsx b/src/components/DetailSectionTop/DetailAddSchedule.tsx index d6fac6dd..faf5982a 100644 --- a/src/components/DetailSectionTop/DetailAddSchedule.tsx +++ b/src/components/DetailSectionTop/DetailAddSchedule.tsx @@ -2,14 +2,35 @@ import * as Dialog from '@radix-ui/react-dialog'; import { CalendarIcon } from '@components/common/icons/Icons'; import Alert from '@components/common/alert/Alert'; import { useNavigate } from 'react-router-dom'; +import { PlusIcon } from '@components/common/icons/Icons'; +import { useGetMyTrips } from '@hooks/useGetMyTrips'; +import { calculateTripDuration } from '@utils/calculateTripDuration'; +import { calculateDayAndDate } from '@utils/utils'; const DetailAddSchedule = () => { + const { myTrips } = useGetMyTrips(); + const tripDuration = calculateTripDuration( + myTrips[0]?.startDate, + myTrips[0]?.endDate, + ); + + const { SmallDayArr } = calculateDayAndDate( + myTrips[0]?.startDate, + myTrips[0]?.endDate, + ); + + console.log(SmallDayArr); + const navigate = useNavigate(); const handleConfirm = () => { navigate('/login'); }; + const handleCreate = () => { + navigate('/create'); + }; + return ( @@ -24,30 +45,51 @@ const DetailAddSchedule = () => { - -
-
-
- -
-
- 강릉 속초 여행 -
-
- 2023.12.20 - 12.22 (3박 4일) + {myTrips.map((trip, index) => { + // 각 여행에 대한 기간을 계산합니다. + const tripDuration = calculateTripDuration( + trip.startDate, + trip.endDate, + ); + + return ( +
+
+
+ {`Thumbnail +
+
+ {trip.tripName} +
+
+ {trip.startDate?.replace(/-/g, '.')} -{' '} + {trip.endDate?.substring(5).replace(/-/g, '.')} ( + {tripDuration}) +
+
-
-
+ ); + })} +
@@ -67,7 +109,7 @@ const DetailAddSchedule = () => { } onConfirm={handleConfirm}>
-
diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 5bc316d1..9ae7a7f8 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -478,6 +478,7 @@ export const PlusIcon: React.FC = ({ size = 20, color = 'black', fill = 'none', + className, }) => { return ( = ({ width={size} height={size} viewBox="0 0 14 14" - fill={fill}> + fill={fill} + className={className}> { + const { data, isLoading, isError } = useQuery({ + queryKey: ['getMyTrips'], + queryFn: () => getMyTrips(), + staleTime: 60000, + }); + + const myTrips = data?.data.data; + + if (isLoading || isError) { + return { myTrips: [] }; + } + + return { myTrips }; +}; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index b371a609..6176f3e0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -30,13 +30,19 @@ export const getEmoji = (content: string) => { export function calculateDayAndDate(startDate: string, endDate: string) { let start = new Date(startDate); const end = new Date(endDate); - const differenceInDays: number = - (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24); - - const DayArr = Array.from( - { length: Math.ceil(differenceInDays) + 1 }, - (_, i) => `DAY ${i + 1}`, + const differenceInDays: number = Math.round( + (end.getTime() - start.getTime()) / (1000 * 3600 * 24), ); + + const createDayArray = (prefix: string) => + Array.from( + { length: differenceInDays + 1 }, + (_, i) => `${prefix} ${i + 1}`, + ); + + const DayArr = createDayArray('DAY'); + const SmallDayArr = createDayArray('Day'); + const DateArr = []; while (start <= end) { @@ -47,5 +53,6 @@ export function calculateDayAndDate(startDate: string, endDate: string) { return { DayArr, DateArr, + SmallDayArr, }; } From 405af799da9f3309981ff0c80dfe5b015bdac86b Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 21 Jan 2024 14:55:43 +0900 Subject: [PATCH 53/62] =?UTF-8?q?Refactor:=20=EC=97=AC=EC=A0=95=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/service.ts | 10 ++-- src/@types/socket.types.ts | 12 ++--- src/@types/trips.types.ts | 6 +-- src/api/socket.ts | 1 - src/api/trips.ts | 10 ++-- src/components/MyTrip/MyTripItem.tsx | 2 +- src/components/Plan/PlanEditItemBox.tsx | 10 +++- src/components/Plan/PlanItem.tsx | 10 ++-- src/components/Plan/PlanMoveItem.tsx | 50 ++++++++++--------- src/components/Plan/PlanSectionTop.tsx | 2 - src/components/Plan/TripBudget.tsx | 5 +- src/components/Trip/EditCodeModal.tsx | 2 +- src/components/Trip/LikedToursList.tsx | 11 ++-- .../LikedToursLists/LikedToursListBox.tsx | 2 +- .../LikedToursLists/LikedToursListItem.tsx | 2 +- src/components/Trip/TripRealtimeEditor.tsx | 1 - src/components/Trip/TripSchedule.tsx | 5 +- src/components/Trip/TripSectionTop.tsx | 5 -- src/hooks/useGetTripsAuthority.ts | 1 - src/hooks/useSocket.ts | 1 - src/pages/plan/AddToTripPlan/OurLiked.tsx | 8 ++- src/pages/plan/addToOurPlace/AddtoListBtn.tsx | 21 ++++---- src/pages/plan/addToOurPlace/MyLiked.tsx | 3 -- src/pages/plan/addToOurPlace/SearchResult.tsx | 10 +--- src/pages/share/shareCode.page.tsx | 14 +++--- src/pages/trip/AddOurList.page.tsx | 1 - src/recoil/socket.ts | 10 ++-- src/router/socketRouter.tsx | 5 +- 28 files changed, 99 insertions(+), 121 deletions(-) diff --git a/src/@types/service.ts b/src/@types/service.ts index de3751a9..bae375b2 100644 --- a/src/@types/service.ts +++ b/src/@types/service.ts @@ -2,7 +2,7 @@ export type subInfoRes = { status: number; message: string; data: { - tripId: number; + tripId: string; startDate: string; endDate: string; numberOfPeople: number; @@ -16,7 +16,7 @@ export type subItemRes = { status: number; message: string; data: { - tripId: number; + tripId: string; visitDate: string; transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; tripItems: { @@ -52,7 +52,7 @@ export type subPathRes = { status: number; message: string; data: { - tripId: number; + tripId: string; visitDate: string; transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; paths: { @@ -77,7 +77,7 @@ export type subMemberRes = { status: number; message: string; data: { - tripId: number; + tripId: string; tripMembers: { memberId: number; name: string; @@ -91,7 +91,7 @@ export type subBudgetRes = { status: number; message: string; data: { - tripId: number; + tripId: string; budget: number; calculatedPrice: number; } | null; diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index 2a70ed7b..49244096 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -2,7 +2,7 @@ type subInfoMessage = (message: { status: number; message: string; data: { - tripId: number; + tripId: string; startDate: string; endDate: string; numberOfPeople: number; @@ -16,7 +16,7 @@ type subItemMessage = (response: { status: number; message: string; data: { - tripId: number; + tripId: string; visitDate: string; transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; tripItems: { @@ -36,7 +36,7 @@ type subPathMessage = (response: { status: number; message: string; data: { - tripId: number; + tripId: string; visitDate: string; transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; paths: { @@ -61,7 +61,7 @@ type subMemberMessage = (response: { status: number; message: string; data: { - tripId: number; + tripId: string; tripMembers: { memberId: number; name: string; @@ -76,7 +76,7 @@ type subBudgetMessage = (response: { status: number; message: string; data: { - tripId: number; + tripId: string; budget: number; calculatedPrice: number; }; @@ -98,7 +98,7 @@ interface pubAddTripItem { } interface pubUpdatePrice { - tripId: number; + tripId: string; visitDate: string; price: number; } diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index 3197ccfe..0b4d17df 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -8,7 +8,7 @@ interface TripRequest { } interface MyTripType { - tripId: number; + tripId: string; tripName: string; startDate: string; endDate: string; @@ -35,7 +35,7 @@ interface ourTripType { } interface ThumbsProps { - tripId: number; + tripId: string; tourId: number; prefer: boolean; notPrefer: boolean; @@ -47,6 +47,6 @@ interface AuthorityType { data: { memberId: number; tripAuthority: string; - TripId: number; + tripId: string; }; } diff --git a/src/api/socket.ts b/src/api/socket.ts index 300d9037..0ade3027 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -79,7 +79,6 @@ export const pubAddTripItem = ( destination: `/pub/trips/${tripId}/addTripItems`, body: JSON.stringify(pubAddTripItem), }); - console.log(pubAddTripItem); }; // 여행 아이템 예상 가격 업데이트 이벤트 발생시 diff --git a/src/api/trips.ts b/src/api/trips.ts index 0f309f3c..9c89db61 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -11,7 +11,7 @@ export const getTrips = async (tripId: string) => { // 여정 기본정보 수정 export const putTrips = async ( - tripId: number, + tripId: string, tourItemId: number, visitDate: string, ) => { @@ -24,7 +24,7 @@ export const putTrips = async ( }; // 여정 탈퇴 -export const deleteTrips = async (tripId: number) => { +export const deleteTrips = async (tripId: string) => { try { const res = await authClient.delete(`trips/${tripId}`); @@ -42,7 +42,7 @@ export const postTrips = async (tripsData: TripRequest) => { // 우리의 관심목록 조회 export const getTripsLike = async ( - tripId: number, + tripId: string, page: number, size: number, ) => { @@ -67,7 +67,7 @@ export const postTripsLike = async (tripId: string, tourItemIds: number[]) => { // 우리의 관심 목록 좋아요/싫어요 export const postTripsLikeHate = async ( - tripId: number, + tripId: string, tourId: number, prefer: boolean, notPrefer: boolean, @@ -113,7 +113,7 @@ export const getTripsjoin = async (tripId: string) => { }; // 여정 참여 -export const postTripsjoin = async (tripId: number, joinCode: string) => { +export const postTripsjoin = async (tripId: string, joinCode: string) => { const res = await authClient.post(`trips/${tripId}/join`, { joinCode }); return res; }; diff --git a/src/components/MyTrip/MyTripItem.tsx b/src/components/MyTrip/MyTripItem.tsx index 2762a3d1..f327aa9c 100644 --- a/src/components/MyTrip/MyTripItem.tsx +++ b/src/components/MyTrip/MyTripItem.tsx @@ -31,7 +31,7 @@ const MyTripItem: React.FC = ({ myTripList }) => { const tripDuration = calculateTripDuration(startDate, endDate); const { mutate: deleteMyTripMutate } = useMutation({ - mutationFn: (tripId: number) => deleteTrips(tripId), + mutationFn: (tripId: string) => deleteTrips(tripId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['myTrips'] }); }, diff --git a/src/components/Plan/PlanEditItemBox.tsx b/src/components/Plan/PlanEditItemBox.tsx index e5b0f944..4c5ce80d 100644 --- a/src/components/Plan/PlanEditItemBox.tsx +++ b/src/components/Plan/PlanEditItemBox.tsx @@ -14,6 +14,8 @@ import { pubUpdateTripItemReq } from '@/@types/service'; import Alert from '@components/common/alert/Alert'; import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; import PlanMoveItem from './PlanMoveItem'; +import { useRecoilState } from 'recoil'; +import { isEditState } from '@recoil/socket'; type PlanItemBoxProps = { item: TripItem[]; @@ -33,7 +35,7 @@ const PlanEditItemBox = ({ } const { callBackPub } = useContext(socketContext); - + const [, setIsEdit] = useRecoilState(isEditState); const [items, setItems] = useState(item); const [newData, setNewData] = useState(null); const [selectedItemId, setSelectedItemId] = useState(null); @@ -78,6 +80,7 @@ const PlanEditItemBox = ({ noun: '여행지', verb: '삭제', })); + setIsEdit(false); }; const handleRadioChange = (id: number | null) => { @@ -105,7 +108,10 @@ const PlanEditItemBox = ({ {(provided) => ( -
+
{day}
{items.map((item, index) => ( = ({ date, day }) => { const navigate = useNavigate(); const { tripAuthority } = useGetTripsAuthority(); - const [isEdit, SetIsEdit] = useState(false); + const [isEdit, setIsEdit] = useRecoilState(isEditState); + const tap = useRecoilValue(tapState); const [, setVisitDate] = useRecoilState(visitDateState); const { tripItem, tripPath, callBackPub, tripId } = useContext(socketContext); @@ -31,11 +32,12 @@ const PlanItem: React.FC = ({ date, day }) => { if (date && tripId) { callBackPub(() => pubGetPathAndItems({ visitDate: date }, tripId)); } + setIsEdit(false); } }, [tap]); const handleEdit = () => { - SetIsEdit((prev) => !prev); + setIsEdit((prev) => !prev); }; const handleTranspo = ( diff --git a/src/components/Plan/PlanMoveItem.tsx b/src/components/Plan/PlanMoveItem.tsx index b06df513..0daa5b5f 100644 --- a/src/components/Plan/PlanMoveItem.tsx +++ b/src/components/Plan/PlanMoveItem.tsx @@ -7,6 +7,8 @@ import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; import { useState, useEffect } from 'react'; import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; +import { useRecoilState } from 'recoil'; +import { isEditState } from '@recoil/socket'; interface PlanMoveItemProps { isCheck: number | null; @@ -19,6 +21,7 @@ const PlanMoveItem: React.FC = ({ tripId, visitDate, }) => { + const [, setIsEdit] = useRecoilState(isEditState); const { callBackPub } = useContext(socketContext); const day = useRecoilValue(dayState); const date = useRecoilValue(dateState); @@ -50,6 +53,7 @@ const PlanMoveItem: React.FC = ({ noun: '날짜 이동', verb: '완료', })); + setIsEdit(false); }; useEffect(() => { @@ -81,31 +85,29 @@ const PlanMoveItem: React.FC = ({ - - + +
-
-
-
-

- 날짜 이동 -

-
-
-
- {day.map((day, index) => ( - - - - ))} -
+
+
+

+ 날짜 이동 +

+
+
+
+ {day.map((day, index) => ( + + + + ))}
diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index f089f621..480ec571 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -15,14 +15,12 @@ import { useEffect } from 'react'; import { useRecoilState } from 'recoil'; import { dayState, dateState } from '@recoil/plan'; import { calculateDayAndDate } from '@utils/utils'; -import { TripSchedule } from '@components/Trip/TripSchedule'; import { useGetTrips } from '@hooks/useGetTrips'; import { visitDateState } from '@recoil/socket'; import { useState } from 'react'; import { getItem } from '@utils/localStorageFun'; import PlanSchedule from './PlanSchedule'; - const PlanSectionTop = () => { const navigate = useNavigate(); const [, setDay] = useRecoilState(dayState); diff --git a/src/components/Plan/TripBudget.tsx b/src/components/Plan/TripBudget.tsx index ee1e5388..97a63c32 100644 --- a/src/components/Plan/TripBudget.tsx +++ b/src/components/Plan/TripBudget.tsx @@ -4,14 +4,11 @@ import { CloseIcon, SettingIcons } from '@components/common/icons/Icons'; import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; import { socketContext } from '@hooks/useSocket'; import * as Progress from '@radix-ui/react-progress'; -import { tripIdState } from '@recoil/socket'; import { useContext, useState } from 'react'; -import { useRecoilValue } from 'recoil'; const TripBudget = () => { const { tripAuthority } = useGetTripsAuthority(); - const { tripBudget } = useContext(socketContext); - const tripId = useRecoilValue(tripIdState); + const { tripBudget, tripId } = useContext(socketContext); const budget = tripBudget?.data; diff --git a/src/components/Trip/EditCodeModal.tsx b/src/components/Trip/EditCodeModal.tsx index 09609bfb..928deef6 100644 --- a/src/components/Trip/EditCodeModal.tsx +++ b/src/components/Trip/EditCodeModal.tsx @@ -16,7 +16,7 @@ const EditCodeModal = () => { const handleConfirm = async () => { if (tripId) { try { - const { data } = await postTripsjoin(Number(tripId), inputCode); + const { data } = await postTripsjoin(tripId, inputCode); if (data.status === 200) { setIsModalOpen(false); } diff --git a/src/components/Trip/LikedToursList.tsx b/src/components/Trip/LikedToursList.tsx index eab8eeea..5587077e 100644 --- a/src/components/Trip/LikedToursList.tsx +++ b/src/components/Trip/LikedToursList.tsx @@ -15,15 +15,16 @@ export const LikedToursList = () => { >(null); const navigate = useNavigate(); - const params = useParams(); + const { id: tripId } = useParams(); - const [selectedTripId, _] = useState(Number(params.id)); + if (!tripId) { + return; + } const { fetchNextPage, hasNextPage, data, isLoading, error } = useInfiniteQuery({ queryKey: ['ourTrips'], - queryFn: ({ pageParam = 0 }) => - getTripsLike(selectedTripId, pageParam, 10), + queryFn: ({ pageParam = 0 }) => getTripsLike(tripId, pageParam, 10), initialPageParam: 0, getNextPageParam: (lastPage) => { if ( @@ -62,7 +63,7 @@ export const LikedToursList = () => { fetchNextPage={fetchNextPage} hasNextPage={hasNextPage} isLoading={isLoading} - selectedTripId={selectedTripId} + selectedTripId={tripId} selectedContentTypeId={selectedContentTypeId} />
diff --git a/src/components/Trip/LikedToursLists/LikedToursListBox.tsx b/src/components/Trip/LikedToursLists/LikedToursListBox.tsx index 56c2db3d..39ef3aae 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListBox.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListBox.tsx @@ -12,7 +12,7 @@ interface LikedToursListProps { hasNextPage: boolean; isLoading: boolean; selectedContentTypeId: number | null; - selectedTripId: number; + selectedTripId: string; } const LikedToursListBox: React.FC = ({ diff --git a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx index 8fb54656..7260e8fa 100644 --- a/src/components/Trip/LikedToursLists/LikedToursListItem.tsx +++ b/src/components/Trip/LikedToursLists/LikedToursListItem.tsx @@ -12,7 +12,7 @@ import { useState } from 'react'; interface LikedToursListItemProps { ourTripList: ourTripType; - selectedTripId: number; + selectedTripId: string; } const LikedToursListItem: React.FC = ({ diff --git a/src/components/Trip/TripRealtimeEditor.tsx b/src/components/Trip/TripRealtimeEditor.tsx index b7f83c6d..3e47bee2 100644 --- a/src/components/Trip/TripRealtimeEditor.tsx +++ b/src/components/Trip/TripRealtimeEditor.tsx @@ -1,4 +1,3 @@ -import { useEffect, useState } from 'react'; import { socketContext } from '@hooks/useSocket'; import { useContext } from 'react'; import { UserIcon } from '@components/common/icons/Icons'; diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index a84d6fd6..ce4f7cf3 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -2,7 +2,6 @@ import { UserIcon } from '@components/common/icons/Icons'; import { useGetTrips } from '@hooks/useGetTrips'; import EditCodeModal from './EditCodeModal'; - export const TripSchedule = () => { const { tripName, startDate, endDate, numberOfPeople } = useGetTrips(); @@ -18,11 +17,11 @@ export const TripSchedule = () => {
-
+ {/*
-
+
*/}
diff --git a/src/components/Trip/TripSectionTop.tsx b/src/components/Trip/TripSectionTop.tsx index a966bab9..d1388108 100644 --- a/src/components/Trip/TripSectionTop.tsx +++ b/src/components/Trip/TripSectionTop.tsx @@ -5,10 +5,6 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import PlanTripButton from './PlanTripButton'; import { LikedToursList } from './LikedToursList'; - - -const TripSectionTop = () => { - const navigate = useNavigate(); import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; import { useEffect, useState } from 'react'; import IsEditableModal from '@components/Share/IsEditableModal'; @@ -26,7 +22,6 @@ const TripSectionTop = () => { } }, [tripAuthority]); - return (
diff --git a/src/hooks/useGetTripsAuthority.ts b/src/hooks/useGetTripsAuthority.ts index 1dd72859..2db402cc 100644 --- a/src/hooks/useGetTripsAuthority.ts +++ b/src/hooks/useGetTripsAuthority.ts @@ -11,7 +11,6 @@ type useGetTripsAuthorityReturn = { export const useGetTripsAuthority = (): useGetTripsAuthorityReturn => { const { id } = useParams(); - const defaultReturn = { tripAuthority: null, memberId: null, diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 37b7831a..d0eeef0f 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -91,7 +91,6 @@ export const useSocket = () => { useEffect(() => { if (tripId && visitDate) { socketConnect(tripId, visitDate.visitDate); - console.log(visitDate); } return () => { diff --git a/src/pages/plan/AddToTripPlan/OurLiked.tsx b/src/pages/plan/AddToTripPlan/OurLiked.tsx index 7b0dae46..3071afe5 100644 --- a/src/pages/plan/AddToTripPlan/OurLiked.tsx +++ b/src/pages/plan/AddToTripPlan/OurLiked.tsx @@ -6,8 +6,10 @@ import { getTripIdFromUrl } from '@utils/getTripIdFromUrl'; import WishCategory from '@components/Wish/WishCategory'; import AddToListButton from '../addToOurPlace/AddtoListBtn'; import { OurLikedList } from './OurLikedList'; +import { useParams } from 'react-router-dom'; export const OurLiked = () => { + const { id: tripId } = useParams(); const [selectedContentTypeId, setSelectedContentTypeId] = useState< null | number >(null); @@ -16,12 +18,10 @@ export const OurLiked = () => { setSelectedContentTypeId(contentTypeId); }; - const tripId = getTripIdFromUrl(); - const { fetchNextPage, hasNextPage, data, isLoading, error } = useInfiniteQuery({ queryKey: ['ourTrips'], - queryFn: ({ pageParam = 0 }) => getTripsLike(tripId, pageParam, 10), + queryFn: ({ pageParam = 0 }) => getTripsLike(tripId || '', pageParam, 10), initialPageParam: 0, getNextPageParam: (lastPage) => { if ( @@ -41,8 +41,6 @@ export const OurLiked = () => { }, }); - console.log('data', data); - if (isLoading) { return ; } diff --git a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx index 6fc1ff16..86cb0bb1 100644 --- a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx +++ b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx @@ -1,9 +1,8 @@ -import { useRecoilValue } from 'recoil'; +import { useRecoilValue, useRecoilState } from 'recoil'; import { selectedItemsState } from '@recoil/listItem'; import { ButtonPrimary } from '@components/common/button/Button'; import { postTripsLike } from '@api/trips'; -import { getTripIdFromUrl } from '@utils/getTripIdFromUrl'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { pubAddTripItem } from '@api/socket'; import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; @@ -14,16 +13,15 @@ const AddToListButton = ({ }: { apiType: 'postTripsLike' | 'putTrips'; }) => { - const selectedTourItemIds = useRecoilValue(selectedItemsState); - console.log('selectedTourItemIds', selectedTourItemIds); + const { id: tripId } = useParams(); + const [selectedTourItemIds, setSelectedTourItemIds] = + useRecoilState(selectedItemsState); const visitDate = useRecoilValue(visitDateState); - console.log('visitDate', visitDate); - + console.log(selectedTourItemIds); const { callBackPub } = useContext(socketContext); const navigate = useNavigate(); const handleAddClick = async () => { - const tripId = getTripIdFromUrl().toString(); if (tripId) { try { let response; @@ -40,11 +38,12 @@ const AddToListButton = ({ newTripItems, }; - console.log('pubAddTripItemData', pubAddTripItemData); callBackPub(() => pubAddTripItem(pubAddTripItemData, tripId)); - navigate(`/trip/${tripId}/plan`); + setTimeout(() => { + setSelectedTourItemIds([]); + navigate(`/trip/${tripId}/plan`); + }, 500); } - console.log('API response:', response); } catch (error) { console.error('API error:', error); } diff --git a/src/pages/plan/addToOurPlace/MyLiked.tsx b/src/pages/plan/addToOurPlace/MyLiked.tsx index 8c9d455c..c31aa717 100644 --- a/src/pages/plan/addToOurPlace/MyLiked.tsx +++ b/src/pages/plan/addToOurPlace/MyLiked.tsx @@ -38,8 +38,6 @@ export const MyLiked = () => { }, }); - console.log('data', data); - if (isLoading) { return ; } @@ -48,7 +46,6 @@ export const MyLiked = () => { } const searchResults = data?.pages.flatMap((page) => page.data.content) || []; - // console.log('searchResults:', searchResults); const noResults = searchResults && searchResults.length === 0; return ( diff --git a/src/pages/plan/addToOurPlace/SearchResult.tsx b/src/pages/plan/addToOurPlace/SearchResult.tsx index 89d42f25..997e0f56 100644 --- a/src/pages/plan/addToOurPlace/SearchResult.tsx +++ b/src/pages/plan/addToOurPlace/SearchResult.tsx @@ -1,7 +1,7 @@ import { getToursSearch } from '@api/tours'; import { useInfiniteQuery } from '@tanstack/react-query'; import ToursCategoryItem from '@components/Tours/ToursCategoryItem'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { Spinner } from '@components/common/spinner/Spinner'; import { ResultCategoryPlan } from './ResultCategoryPlan'; @@ -16,19 +16,11 @@ export const SearchResultForPlan = ({ }: SearchResultProps) => { const categories = ['전체', '숙소', '식당', '관광지']; const [selectedCategory, setSelectedCategory] = useState('전체'); - useEffect(() => { - console.log(selectedCategory); - }, [selectedCategory]); const handleSelectCategory = (category: string) => { setSelectedCategory(category); }; - useEffect(() => { - console.log('searchWord: ' + searchWord); - }, [searchWord]); - console.log(); - const { data, fetchNextPage, diff --git a/src/pages/share/shareCode.page.tsx b/src/pages/share/shareCode.page.tsx index 587e9187..817c7801 100644 --- a/src/pages/share/shareCode.page.tsx +++ b/src/pages/share/shareCode.page.tsx @@ -6,14 +6,14 @@ import { useNavigate } from 'react-router-dom'; const shareCode = () => { const navigate = useNavigate(); - const { tripAuthority, TripId } = useGetTripsAuthority(); + const { tripAuthority, tripId } = useGetTripsAuthority(); useEffect(() => { - if (tripAuthority === 'WRITE' && TripId) { + if (tripAuthority === 'WRITE' && tripId) { alert('이미 편집 가능한 여정입니다.'); - navigate(`/trip/${TripId}`, { replace: true }); + navigate(`/trip/${tripId}`, { replace: true }); } - }, [tripAuthority, TripId]); + }, [tripAuthority, tripId]); const [inputCode, setInputCode] = useState(''); const [showError, setShowError] = useState(false); @@ -23,11 +23,11 @@ const shareCode = () => { if (changeValue.length <= 5) { setInputCode(e.target.value); } - if (changeValue.length === 5 && TripId) { + if (changeValue.length === 5 && tripId) { try { - const { data } = await postTripsjoin(TripId, changeValue); + const { data } = await postTripsjoin(tripId, changeValue); if (data.status === 200) { - navigate(`/trip/${TripId}`, { replace: true }); + navigate(`/trip/${tripId}`, { replace: true }); } } catch (err) { setShowError(true); diff --git a/src/pages/trip/AddOurList.page.tsx b/src/pages/trip/AddOurList.page.tsx index 14ce38b8..14eaf416 100644 --- a/src/pages/trip/AddOurList.page.tsx +++ b/src/pages/trip/AddOurList.page.tsx @@ -6,7 +6,6 @@ import { useLocation } from 'react-router-dom'; export const AddOurList = () => { const location = useLocation(); - const queryParams = new URLSearchParams(location.search); const searchWordFromQuery = queryParams.get('searchWord'); diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts index fca451c7..f8a995c9 100644 --- a/src/recoil/socket.ts +++ b/src/recoil/socket.ts @@ -1,11 +1,11 @@ import { atom } from 'recoil'; -export const tripIdState = atom({ - key: 'tripIdState', - default: '', -}); - export const visitDateState = atom<{ visitDate: string } | null>({ key: 'visitDateState', default: { visitDate: '' }, }); + +export const isEditState = atom({ + key: 'isEditState', + default: false, +}); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 9892bd95..e99a1ecc 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -5,12 +5,9 @@ import { PlanAddPlace } from '@pages/plan/addToOurPlace/PlanAddPlace.page'; import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; -import { useRecoilValue } from 'recoil'; -import { tripIdState, visitDateState } from '@recoil/socket'; import Share from '@pages/share/share.page'; import ShareCode from '@pages/share/shareCode.page'; -import { AddOurList } from '@pages/trip/AddOurList'; - +import { AddOurList } from '@pages/trip/AddOurList.page'; const SocketRoutes = () => { return ( From 47fd1c53f967372f68bfe4519f4063ba7aaf8ad3 Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 21 Jan 2024 14:58:21 +0900 Subject: [PATCH 54/62] =?UTF-8?q?Fix:=20=EB=B9=8C=EB=93=9C=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DetailSectionTop/DetailAddSchedule.tsx | 4 ---- src/pages/plan/AddToTripPlan/OurLiked.tsx | 1 - 2 files changed, 5 deletions(-) diff --git a/src/components/DetailSectionTop/DetailAddSchedule.tsx b/src/components/DetailSectionTop/DetailAddSchedule.tsx index faf5982a..57880903 100644 --- a/src/components/DetailSectionTop/DetailAddSchedule.tsx +++ b/src/components/DetailSectionTop/DetailAddSchedule.tsx @@ -9,10 +9,6 @@ import { calculateDayAndDate } from '@utils/utils'; const DetailAddSchedule = () => { const { myTrips } = useGetMyTrips(); - const tripDuration = calculateTripDuration( - myTrips[0]?.startDate, - myTrips[0]?.endDate, - ); const { SmallDayArr } = calculateDayAndDate( myTrips[0]?.startDate, diff --git a/src/pages/plan/AddToTripPlan/OurLiked.tsx b/src/pages/plan/AddToTripPlan/OurLiked.tsx index 3071afe5..8737ae66 100644 --- a/src/pages/plan/AddToTripPlan/OurLiked.tsx +++ b/src/pages/plan/AddToTripPlan/OurLiked.tsx @@ -2,7 +2,6 @@ import { useInfiniteQuery } from '@tanstack/react-query'; import { useState } from 'react'; import { Spinner } from '@components/common/spinner/Spinner'; import { getTripsLike } from '@api/trips'; -import { getTripIdFromUrl } from '@utils/getTripIdFromUrl'; import WishCategory from '@components/Wish/WishCategory'; import AddToListButton from '../addToOurPlace/AddtoListBtn'; import { OurLikedList } from './OurLikedList'; From 9ab1d22c40f3f780a44ca0889fd764148624a96a Mon Sep 17 00:00:00 2001 From: sue Date: Sun, 21 Jan 2024 16:48:05 +0900 Subject: [PATCH 55/62] =?UTF-8?q?Design:=20=EC=97=AC=EC=A0=95=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=91=20=EB=A7=88=ED=81=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/trip/tripEdit.page.tsx | 55 ++++++++++++++++++++++++++++++++ src/router/socketRouter.tsx | 2 ++ 2 files changed, 57 insertions(+) create mode 100644 src/pages/trip/tripEdit.page.tsx diff --git a/src/pages/trip/tripEdit.page.tsx b/src/pages/trip/tripEdit.page.tsx new file mode 100644 index 00000000..2f95e5c1 --- /dev/null +++ b/src/pages/trip/tripEdit.page.tsx @@ -0,0 +1,55 @@ +import { BackBox } from '@components/common'; +import { + CalendarIcon, + PaperIcon, + SearchIcon, + UserIcon, +} from '@components/common/icons/Icons'; + +const TripEdit = () => { + return ( + <> + 여정 수정하기 + +
+
+
+ +
+

나의 여정 N

+
+ +
+
+ +
+

인원

+
+ +
+
+ +
+

+ 2023.12.14 ~ 2024.12.16 +

+
+ +
+
+ +
+

+ 강릉 ・ 속초 +

+
+ + +
+ + ); +}; + +export default TripEdit; diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index e679617b..c1afe104 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -8,6 +8,7 @@ import MainLayout from './routerLayout'; import { useRecoilValue } from 'recoil'; import { tripIdState, visitDateState } from '@recoil/socket'; import { AddOurList } from '@pages/trip/AddOurList'; +import TripEdit from '@pages/trip/tripEdit.page'; const SocketRoutes = () => { const tripId = useRecoilValue(tripIdState); @@ -33,6 +34,7 @@ const SocketRouter = () => { }> } /> } /> + } /> } /> From 09ce832e8e34fdba8014cacd5d945c5a8667a174 Mon Sep 17 00:00:00 2001 From: Hojin Date: Mon, 22 Jan 2024 00:33:17 +0900 Subject: [PATCH 56/62] =?UTF-8?q?Feat:=20=EC=83=81=ED=92=88=EA=B0=80?= =?UTF-8?q?=EA=B2=A9=20=EC=88=98=EC=A0=95=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/socket.types.ts | 2 +- src/api/socket.ts | 2 +- src/components/Plan/PlanEditItemBox.tsx | 14 +++--- src/components/Plan/PlanItem.tsx | 1 + src/components/Plan/PlanItemBox.tsx | 66 ++++++++++++++++++++++++- src/hooks/useSocket.ts | 2 + 6 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index 49244096..a8167cc8 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -100,7 +100,7 @@ interface pubAddTripItem { interface pubUpdatePrice { tripId: string; visitDate: string; - price: number; + price: string; } interface pubUpdateTripItem { diff --git a/src/api/socket.ts b/src/api/socket.ts index 0ade3027..8a32b63f 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -84,7 +84,7 @@ export const pubAddTripItem = ( // 여행 아이템 예상 가격 업데이트 이벤트 발생시 export const pubUpdatePrice = ( pubUpdatePrice: pubUpdatePrice, - tripItemId: string, + tripItemId: number, ) => { socketClient.publish({ destination: `/pub/tripItems/${tripItemId}/updatePrice`, diff --git a/src/components/Plan/PlanEditItemBox.tsx b/src/components/Plan/PlanEditItemBox.tsx index 4c5ce80d..6919d327 100644 --- a/src/components/Plan/PlanEditItemBox.tsx +++ b/src/components/Plan/PlanEditItemBox.tsx @@ -1,4 +1,4 @@ -import { PenIcon, DragAndDropIcon } from '@components/common/icons/Icons'; +import { DragAndDropIcon } from '@components/common/icons/Icons'; import { TripItem } from '@/@types/service'; import { DragDropContext, @@ -71,9 +71,10 @@ const PlanEditItemBox = ({ const handleConfirm = () => { if (tripId && visitDate && selectedItemId) { - callBackPub(() => - pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId), - ); + pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId); + // callBackPub(() => + // pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId), + // ); } setToastPopUp(() => ({ isPopUp: true, @@ -139,9 +140,8 @@ const PlanEditItemBox = ({ alt="img" />
-
+
{item.name} -
{item.category} @@ -166,7 +166,7 @@ const PlanEditItemBox = ({ )} -
+
= ({ date, day }) => { item={tripItem?.data?.tripItems || []} paths={tripPath?.data?.paths || []} transportation={transpo} + visitDate={date || ''} day={day} /> )} diff --git a/src/components/Plan/PlanItemBox.tsx b/src/components/Plan/PlanItemBox.tsx index d54a922c..7e26250c 100644 --- a/src/components/Plan/PlanItemBox.tsx +++ b/src/components/Plan/PlanItemBox.tsx @@ -3,15 +3,22 @@ import { CarIcon, BusIcon, SequenceIcon, + CloseIcon, } from '@components/common/icons/Icons'; import { TripItem, Paths } from '@/@types/service'; import { v4 as uuidv4 } from 'uuid'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; +import Alert from '@components/common/alert/Alert'; +import { useContext, useState } from 'react'; +import { socketContext } from '@hooks/useSocket'; +import { pubUpdatePrice } from '@api/socket'; type PlanItemBoxProps = { item: TripItem[]; paths: Paths[]; transportation: string; day: string; + visitDate: string; }; const PlanItemBox = ({ @@ -19,12 +26,32 @@ const PlanItemBox = ({ paths, transportation, day, + visitDate, }: PlanItemBoxProps) => { if (!item || !paths) { return
Missing data
; } + const { tripAuthority } = useGetTripsAuthority(); + const { tripId } = useContext(socketContext); + const itemLength = item.length; + const [inputPrice, setInputPrice] = useState(''); + const showCloseIcon = inputPrice; + + const handlePrice = (inputBudget: string, tripItemId: number) => { + if (inputBudget && tripItemId) { + pubUpdatePrice( + { + tripId: tripId, + visitDate: visitDate, + price: inputBudget, + }, + tripItemId, + ); + setInputPrice(''); + } + }; return ( <> @@ -50,7 +77,44 @@ const PlanItemBox = ({
{item.name} - + {tripAuthority == 'WRITE' && ( + + handlePrice(inputPrice, item.tripItemId) + } + closeOnConfirm={true} + children={ + + } + content={ +
+
+ setInputPrice(e.target.value)} + /> +
setInputPrice('')}> + {showCloseIcon && ( + + )} +
+
+ + 원 + +
+ } + /> + )}
{item.category} diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index d0eeef0f..eb9b0520 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -92,9 +92,11 @@ export const useSocket = () => { if (tripId && visitDate) { socketConnect(tripId, visitDate.visitDate); } + console.log('소켓연결'); return () => { socketClient.deactivate(); + console.log('소켓해제'); }; }, [tripId, visitDate, socketCallback]); From 6c06d4e620029caae9fb559d40605ad5d725d921 Mon Sep 17 00:00:00 2001 From: Hojin Date: Mon, 22 Jan 2024 01:15:57 +0900 Subject: [PATCH 57/62] =?UTF-8?q?Refactor:=20=EC=97=AC=EC=A0=95=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=ED=85=9C=20=EB=AC=B8=EC=9E=90=EC=97=B4=20?= =?UTF-8?q?=EB=84=98=EC=B9=A8=EB=B0=A9=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/socket.ts | 4 ++-- src/components/Plan/PlanEditItemBox.tsx | 11 ++++++----- src/components/Plan/PlanItemBox.tsx | 4 +++- src/components/Plan/TripBudget.tsx | 14 ++++++++------ 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/api/socket.ts b/src/api/socket.ts index 8a32b63f..c5c437b4 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -106,10 +106,10 @@ export const pubUpdateTripItem = ( // 여행 날짜별 교통 수단 변경 이벤트 발생시 (01/16 업데이트) export const pubUpdateTransportation = ( pubUpdateTransportation: pubUpdateTransportation, - trips: string, + tripId: string, ) => { socketClient.publish({ - destination: `/pub/trips/${trips}/updateTransportation`, + destination: `/pub/trips/${tripId}/updateTransportation`, body: JSON.stringify(pubUpdateTransportation), }); }; diff --git a/src/components/Plan/PlanEditItemBox.tsx b/src/components/Plan/PlanEditItemBox.tsx index 6919d327..1e1a6fec 100644 --- a/src/components/Plan/PlanEditItemBox.tsx +++ b/src/components/Plan/PlanEditItemBox.tsx @@ -71,10 +71,9 @@ const PlanEditItemBox = ({ const handleConfirm = () => { if (tripId && visitDate && selectedItemId) { - pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId); - // callBackPub(() => - // pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId), - // ); + callBackPub(() => + pubDeleteItem({ tripId: tripId, visitDate: visitDate }, selectedItemId), + ); } setToastPopUp(() => ({ isPopUp: true, @@ -141,7 +140,9 @@ const PlanEditItemBox = ({ />
- {item.name} + {item.name.length > 17 + ? item.name.slice(0, 17) + '...' + : item.name}
{item.category} diff --git a/src/components/Plan/PlanItemBox.tsx b/src/components/Plan/PlanItemBox.tsx index 7e26250c..40146f9a 100644 --- a/src/components/Plan/PlanItemBox.tsx +++ b/src/components/Plan/PlanItemBox.tsx @@ -76,7 +76,9 @@ const PlanItemBox = ({ />
- {item.name} + {item.name.length > 19 + ? item.name.slice(0, 19) + '...' + : item.name} {tripAuthority == 'WRITE' && ( { const { tripAuthority } = useGetTripsAuthority(); - const { tripBudget, tripId } = useContext(socketContext); + const { callBackPub, tripBudget, tripId } = useContext(socketContext); const budget = tripBudget?.data; @@ -28,11 +28,13 @@ const TripBudget = () => { const handleSetTargetBudget = (inputBudget: string) => { const newTargetBudget = parseInt(inputBudget, 10); // 문자열 숫자로 변환 if (!isNaN(newTargetBudget) && newTargetBudget !== budget?.budget) { - pubUpdateBudget( - { - budget: newTargetBudget, - }, - tripId || '', + callBackPub(() => + pubUpdateBudget( + { + budget: newTargetBudget, + }, + tripId || '', + ), ); setInputBudget(''); } From 0c5847cf2cfd9c31f8476ccb313b2d2ecfd37859 Mon Sep 17 00:00:00 2001 From: sue Date: Mon, 22 Jan 2024 04:50:12 +0900 Subject: [PATCH 58/62] =?UTF-8?q?Feat:=20=EC=97=AC=EC=A0=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/trips.types.ts | 6 +++--- src/api/trips.ts | 9 +++++++++ src/components/Trip/TripSchedule.tsx | 5 ----- src/pages/plan/AddToTripPlan/OurLiked.tsx | 2 +- src/pages/plan/addToOurPlace/AddtoListBtn.tsx | 4 ++-- src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx | 2 +- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index 0b4d17df..6b6bceec 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -3,8 +3,8 @@ interface TripRequest { numberOfPeople: number; startDate: string | null; endDate: string | null; - area: string | null; - subarea: string | null; + area?: string | null; + subarea?: string | null; } interface MyTripType { @@ -40,7 +40,7 @@ interface ThumbsProps { prefer: boolean; notPrefer: boolean; } - + interface AuthorityType { status: number; message: string; diff --git a/src/api/trips.ts b/src/api/trips.ts index 9c89db61..0a89bb54 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -11,6 +11,15 @@ export const getTrips = async (tripId: string) => { // 여정 기본정보 수정 export const putTrips = async ( + tripId: string, + tripRequestData: TripRequest, +) => { + const res = await authClient.put(`trips/${tripId}`, tripRequestData); + return res; +}; + +// 여행 상세페이지에서 여정에 여행지 등록 +export const postTripsItem = async ( tripId: string, tourItemId: number, visitDate: string, diff --git a/src/components/Trip/TripSchedule.tsx b/src/components/Trip/TripSchedule.tsx index ce4f7cf3..79a8c178 100644 --- a/src/components/Trip/TripSchedule.tsx +++ b/src/components/Trip/TripSchedule.tsx @@ -17,11 +17,6 @@ export const TripSchedule = () => {
- {/*
- -
*/}
diff --git a/src/pages/plan/AddToTripPlan/OurLiked.tsx b/src/pages/plan/AddToTripPlan/OurLiked.tsx index 8737ae66..f80e6ef2 100644 --- a/src/pages/plan/AddToTripPlan/OurLiked.tsx +++ b/src/pages/plan/AddToTripPlan/OurLiked.tsx @@ -68,7 +68,7 @@ export const OurLiked = () => { /> )}
- +
); diff --git a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx index 86cb0bb1..4d74e9c8 100644 --- a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx +++ b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx @@ -11,7 +11,7 @@ import { visitDateState } from '@recoil/socket'; const AddToListButton = ({ apiType, }: { - apiType: 'postTripsLike' | 'putTrips'; + apiType: 'postTripsLike' | 'postTripsItem'; }) => { const { id: tripId } = useParams(); const [selectedTourItemIds, setSelectedTourItemIds] = @@ -28,7 +28,7 @@ const AddToListButton = ({ if (apiType === 'postTripsLike') { response = await postTripsLike(tripId, selectedTourItemIds); navigate(`/trip/${tripId}`); - } else if (apiType === 'putTrips' && visitDate) { + } else if (apiType === 'postTripsItem' && visitDate) { const newTripItems = selectedTourItemIds.map((tourItemId) => ({ tourItemId: tourItemId, })); diff --git a/src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx b/src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx index c87b6cb9..b8988d18 100644 --- a/src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx +++ b/src/pages/plan/addToOurPlace/ResultCategoryPlan.tsx @@ -10,7 +10,7 @@ interface ResultCategoryProps { fetchNextPage: (() => Promise>) | null; hasNextPage: boolean; isFetchingNextPage: boolean; - apiType: 'postTripsLike' | 'putTrips'; + apiType: 'postTripsLike' | 'postTripsItem'; } export const ResultCategoryPlan = ({ From 2ca114d6024f38c7f5600bf86945dd01d9bc5794 Mon Sep 17 00:00:00 2001 From: sue Date: Mon, 22 Jan 2024 04:50:46 +0900 Subject: [PATCH 59/62] =?UTF-8?q?Feat:=20=EC=97=AC=EC=A0=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=82=AD=EC=A0=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Trip/EditCodeModal.tsx | 72 ++++++- .../common/toastpopup/ToastPopUp.tsx | 2 +- src/hooks/useCounter.ts | 6 +- src/pages/trip/tripEdit.page.tsx | 191 ++++++++++++++---- 4 files changed, 227 insertions(+), 44 deletions(-) diff --git a/src/components/Trip/EditCodeModal.tsx b/src/components/Trip/EditCodeModal.tsx index 928deef6..7d3ca648 100644 --- a/src/components/Trip/EditCodeModal.tsx +++ b/src/components/Trip/EditCodeModal.tsx @@ -1,18 +1,44 @@ -import { postTripsjoin } from '@api/trips'; +import { deleteTrips, postTripsjoin } from '@api/trips'; import CodeInput from '@components/Share/CodeInput'; import Alert from '@components/common/alert/Alert'; import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; import { useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; +import * as Dialog from '@radix-ui/react-dialog'; +import { DeleteIcon, PenIcon } from '@components/common/icons/Icons'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import ToastPopUp from '@components/common/toastpopup/ToastPopUp'; const EditCodeModal = () => { + const navigate = useNavigate(); const [isModalOpen, setIsModalOpen] = useState(false); const [inputCode, setInputCode] = useState(''); const [showError, setShowError] = useState(false); + const [isEditModal, setIsEditModal] = useState(false); + const [isToastVisible, setIsToastVisible] = useState(false); const { id: tripId } = useParams(); const { tripAuthority } = useGetTripsAuthority(); + const queryClient = useQueryClient(); + + const { mutate: deleteMutate } = useMutation({ + mutationFn: (tripId: string) => deleteTrips(tripId), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['myTrips'] }); + }, + onError: () => console.log('error'), + }); + + const handleDelete = () => { + if (tripId) { + deleteMutate(tripId); + } + setIsEditModal(false); + setIsToastVisible(true); + setTimeout(() => navigate('/mytrip'), 2000); + }; + const handleConfirm = async () => { if (tripId) { try { @@ -30,10 +56,46 @@ const EditCodeModal = () => { return ( <> + {isToastVisible && } {tripAuthority === 'WRITE' ? ( - + + + + + {isEditModal && ( + + + + + 나의 여정 + + + <> + + + + + + + + )} + ) : ( = ({ noun, verb }) => { }, []); useEffect(() => { - if (noun === '일정' || noun === '날짜 이동') { + if (noun === '일정' || noun === '날짜 이동' || noun === '여행 일정') { setParticle('이'); } }, [noun]); diff --git a/src/hooks/useCounter.ts b/src/hooks/useCounter.ts index 4ff26ba9..f5465463 100644 --- a/src/hooks/useCounter.ts +++ b/src/hooks/useCounter.ts @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; const useCounter = ( initialValue: number = 0, @@ -7,6 +7,10 @@ const useCounter = ( ): [number, () => void, () => void] => { const [value, setValue] = useState(initialValue); + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + const increase = () => { setValue((prevValue) => Math.min(prevValue + 1, max)); }; diff --git a/src/pages/trip/tripEdit.page.tsx b/src/pages/trip/tripEdit.page.tsx index 2f95e5c1..cd9cb371 100644 --- a/src/pages/trip/tripEdit.page.tsx +++ b/src/pages/trip/tripEdit.page.tsx @@ -1,54 +1,171 @@ +import { putTrips } from '@api/trips'; import { BackBox } from '@components/common'; +import { ButtonPrimary } from '@components/common/button/Button'; import { CalendarIcon, - PaperIcon, - SearchIcon, + CloseIcon, + CounterIcon, + PlanIcon, UserIcon, } from '@components/common/icons/Icons'; +import { InputField } from '@components/createTrip/InputField'; +import useCounter from '@hooks/useCounter'; +import { useGetTrips } from '@hooks/useGetTrips'; +import { useGetTripsAuthority } from '@hooks/useGetTripsAuthority'; +import { tripDateState } from '@recoil/tripDate'; +import { formatDate } from '@utils/formatDate'; +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useRecoilState } from 'recoil'; +import { SelectDate } from '../../components/createTrip/SelectDate'; const TripEdit = () => { - return ( - <> - 여정 수정하기 + const navigate = useNavigate(); + const tripId = useGetTripsAuthority().tripId; + const { tripName, numberOfPeople, startDate, endDate } = useGetTrips(); -
-
-
- -
-

나의 여정 N

-
+ const [title, setTitle] = useState(''); + const [numOfMembers, increaseNumOfMembers, decreaseNumOfMembers] = useCounter( + numberOfPeople ?? 1, + 1, + ); + const [showSelectDate, setShowSelectDate] = useState(false); + const [tripDate, setTripDate] = useRecoilState(tripDateState); -
-
- -
-

인원

-
+ let start: Date, end: Date; + if (startDate && endDate) { + start = new Date(startDate); + end = new Date(endDate); + } -
-
- -
-

- 2023.12.14 ~ 2024.12.16 -

-
+ useEffect(() => { + if (startDate && endDate) { + setTripDate({ startDate: start, endDate: end }); + } + if (tripName) { + setTitle(tripName); + } + }, [tripName, startDate, endDate]); + + const handleSubmit = async () => { + try { + let adjustedStartDate, adjustedEndDate; -
-
- + if (tripDate.startDate) { + adjustedStartDate = new Date(tripDate.startDate); + adjustedStartDate.setDate(adjustedStartDate.getDate() + 1); + } + if (tripDate.endDate) { + adjustedEndDate = new Date(tripDate.endDate); + adjustedEndDate.setDate(adjustedEndDate.getDate() + 1); + } + + const tripRequestData = { + tripName: title, + numberOfPeople: numOfMembers, + startDate: adjustedStartDate + ? adjustedStartDate.toISOString().split('T')[0] + : null, + endDate: adjustedEndDate + ? adjustedEndDate.toISOString().split('T')[0] + : null, + }; + + if (tripId) { + const response = await putTrips(tripId, tripRequestData); + console.log('전송 완료: ', response); + navigate('/trip/' + tripId); + window.location.reload(); + } + } catch (error) { + console.error('전송 실패: ', error); + } + }; + + const formattedTripDate = + tripDate.startDate && tripDate.endDate + ? tripDate.startDate === tripDate.endDate + ? formatDate(tripDate.startDate, 'yyyy. MM. dd') + : `${formatDate(tripDate.startDate, 'yyyy. MM. dd')} - ${formatDate( + tripDate.endDate, + 'MM. dd', + )}` + : '여행 날짜 (선택)'; + + if (showSelectDate) { + return ( + { + setShowSelectDate(false); + }} + /> + ); + } + return ( +
+ { + navigate(-1); + }} + children="여정 수정하기" + /> +
+ + + { + setTitle(e.target.value); + }} + autoFocus + /> + {title && ( +
{ + setTitle(''); + }}> +
-

- 강릉 ・ 속초 -

+ )} +
+ + +
인원
+
+ {numOfMembers !== 1 && ( + + )} +
{numOfMembers}
+
+
+ + { + setShowSelectDate(true); + }} + isClickable> +
{formattedTripDate}
+
- - - +
+ 완료 +
+
); }; From 838344c7bb25c9ebc1060a19ab6bd90833b2265a Mon Sep 17 00:00:00 2001 From: sue Date: Mon, 22 Jan 2024 04:57:23 +0900 Subject: [PATCH 60/62] =?UTF-8?q?Chore:=20=EB=B9=8C=EB=93=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx | 2 +- src/pages/plan/addToOurPlace/SearchResult.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx b/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx index 4fcfa8bf..faac0821 100644 --- a/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx +++ b/src/pages/plan/addToOurPlace/PlanAddPlace.page.tsx @@ -23,7 +23,7 @@ export const PlanAddPlace = () => {
{searchWord ? ( - + ) : ( )} diff --git a/src/pages/plan/addToOurPlace/SearchResult.tsx b/src/pages/plan/addToOurPlace/SearchResult.tsx index 997e0f56..47573b93 100644 --- a/src/pages/plan/addToOurPlace/SearchResult.tsx +++ b/src/pages/plan/addToOurPlace/SearchResult.tsx @@ -7,7 +7,7 @@ import { ResultCategoryPlan } from './ResultCategoryPlan'; interface SearchResultProps { searchWord: string; - apiType: 'postTripsLike' | 'putTrips'; + apiType: 'postTripsLike' | 'postTripsItem'; } export const SearchResultForPlan = ({ From b42e97d0fa0512a01832110bb55b849587ba425c Mon Sep 17 00:00:00 2001 From: sue Date: Mon, 22 Jan 2024 05:25:26 +0900 Subject: [PATCH 61/62] =?UTF-8?q?Design:=20=EA=B2=BD=EB=B9=84=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/TripBudget.tsx | 65 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/components/Plan/TripBudget.tsx b/src/components/Plan/TripBudget.tsx index 97a63c32..0cd9d2a6 100644 --- a/src/components/Plan/TripBudget.tsx +++ b/src/components/Plan/TripBudget.tsx @@ -40,11 +40,11 @@ const TripBudget = () => { return ( <> -
+
사용 경비
- {budget?.calculatedPrice.toLocaleString() ?? '-'} + {budget?.calculatedPrice.toLocaleString() ?? 0}
@@ -67,44 +67,47 @@ const TripBudget = () => { /> -
-
- 목표 경비 +
+
+ + 목표 경비 + {tripAuthority == 'WRITE' && ( handleSetTargetBudget(inputBudget)} + onCancel={() => setInputBudget('')} closeOnConfirm={true} children={ } content={ @@ -112,13 +115,13 @@ const TripBudget = () => {
setInputBudget(e.target.value)} />
setInputBudget('')}> {showCloseIcon && ( @@ -126,13 +129,15 @@ const TripBudget = () => {
- + + 원 +
} /> )}
-
+
{budget?.budget.toLocaleString() ?? '- '}
From 49a350155014080a0313afdafc1c9be413388806 Mon Sep 17 00:00:00 2001 From: sue Date: Mon, 22 Jan 2024 05:37:06 +0900 Subject: [PATCH 62/62] =?UTF-8?q?Chore:=20=EB=B9=8C=EB=93=9C=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/plan/addToOurPlace/AddtoListBtn.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx index 4d74e9c8..ea7589f6 100644 --- a/src/pages/plan/addToOurPlace/AddtoListBtn.tsx +++ b/src/pages/plan/addToOurPlace/AddtoListBtn.tsx @@ -24,9 +24,8 @@ const AddToListButton = ({ const handleAddClick = async () => { if (tripId) { try { - let response; if (apiType === 'postTripsLike') { - response = await postTripsLike(tripId, selectedTourItemIds); + await postTripsLike(tripId, selectedTourItemIds); navigate(`/trip/${tripId}`); } else if (apiType === 'postTripsItem' && visitDate) { const newTripItems = selectedTourItemIds.map((tourItemId) => ({