From 2ee0ebd6ddb2415e9337950ba3b33e768788f4a5 Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 14 Jan 2024 10:24:04 +0900 Subject: [PATCH 01/16] =?UTF-8?q?Feat:=20=EC=86=8C=EC=BC=93=20=EB=AA=85?= =?UTF-8?q?=EC=84=B8=20=EB=B0=8F=20=EC=B6=94=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/socket.types.ts | 44 +++++++ src/api/socket.ts | 142 ++++++++++++++++++++++ src/components/Plan/PlanItem.tsx | 57 +++++++++ src/components/Plan/PlanSectionTop.tsx | 2 + src/components/common/icons/Icons.tsx | 2 +- src/utils/socket.ts | 159 ------------------------- 6 files changed, 246 insertions(+), 160 deletions(-) create mode 100644 src/@types/socket.types.ts create mode 100644 src/components/Plan/PlanItem.tsx delete mode 100644 src/utils/socket.ts diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts new file mode 100644 index 00000000..11433be8 --- /dev/null +++ b/src/@types/socket.types.ts @@ -0,0 +1,44 @@ +interface pubInfo { + startDate: string; + endDate: string; + numberOfPeople: number; + tripName: string; + tripStatus: 'BEFORE' | 'DURING' | 'AFTER'; + area: string; + subarea: string; + budget: number; +} + +interface pubAddTripItem { + visitDate: string; + newTripItems: { + tourItemId: number; + }[]; +} + +interface pubUpdateTripItem { + visitDate: string; + tripItemOrder: { + tripItemId: number; + seqNum: number; + }[]; +} + +interface pubVisitDate { + // visitDate: '2024-01-07', + visitDate: string; +} + +interface pubUpdatePrice { + price: number; +} + +interface pubUpdateTransportation { + transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; +} + + + +interface pubMember { + memberId: number; +} diff --git a/src/api/socket.ts b/src/api/socket.ts index a35d44e9..d69a9281 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -3,3 +3,145 @@ import * as StompJs from '@stomp/stompjs'; export const socketClient = new StompJs.Client({ brokerURL: import.meta.env.VITE_SOCKET_URL, }); + +// 소켓 구독 +// 여정 기본 정보 +export const subInfo = (tripId: number) => { + socketClient.subscribe(`/sub/${tripId}/info`, (message) => { + console.log(`기본정보 변경 이벤트:`, message.body); + }); +}; + +// 방문 날짜별 여정 여행 아이템 정보 +export const subItem = (tripId: number, visitDate: string) => { + socketClient.subscribe(`/sub/${tripId}/tripItems/${visitDate}`, (message) => { + console.log(`방문날짜별 여정 여행 아이템 정보:`, message.body); + }); +}; + +// 방문 날짜별 여정 경로 정보 +export const subPath = (tripId: number, visitDate: string) => { + socketClient.subscribe(`/sub/${tripId}/path/${visitDate}`, (message) => { + console.log(`방문날짜별 여정경로 정보:`, message.body); + }); +}; + +// 연결된 멤버 정보 +export const subMember = (tripId: number) => { + socketClient.subscribe(`/sub/${tripId}/connectedMember`, (message) => { + console.log(`연결된 멤버 정보 :`, message.body); + }); +}; + +// 목표 경비, 실제 발생 비용 +export const subBudget = (tripId: number) => { + socketClient.subscribe(`/sub/${tripId}/budget`, (message) => { + console.log(`목표 경비, 실제 발생 비용:`, message.body); + }); +}; + +// 소켓 전송 +// 여정 기본 정보 변경 이벤트 발생시 +export const pubInfo = (pubInfo: pubInfo, tripId: number) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/info`, + body: JSON.stringify(pubInfo), + }); +}; + +// 여정에 여행 아이템 추가 이벤트 발생시 +export const pubAddTripItem = ( + pubAddTripItem: pubAddTripItem, + tripId: number, +) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/addTripItems`, + body: JSON.stringify(pubAddTripItem), + }); +}; + +// 여행 아이템 예상 가격 업데이트 이벤트 발생시 +export const pubUpdatePrice = ( + pubUpdatePrice: pubUpdatePrice, + tripItemId: number, +) => { + socketClient.publish({ + destination: `/pub/tripItems/${tripItemId}/updatePrice`, + body: JSON.stringify(pubUpdatePrice), + }); +}; + +// 여행 아이템 방문 순서 변경 이벤트 발생시 +export const pubUpdateTripItem = ( + pubUpdateTripItem: pubUpdateTripItem, + tripId: number, +) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/updateTripItemOrder`, + body: JSON.stringify(pubUpdateTripItem), + }); +}; + +// 여행 아이템 방문 교통 수단 변경 이벤트 발생시 +export const pubUpdateTransportation = ( + pubUpdateTransportation: pubUpdateTransportation, + tripItemId: number, +) => { + socketClient.publish({ + destination: `/pub/tripItems/${tripItemId}/updateTransportation`, + body: JSON.stringify(pubUpdateTransportation), + }); +}; + +// 여행 아이템 방문 날짜 변경 이벤트 발생시 +export const pubUpdateVisitDate = ( + pubUpdateVisitDate: pubVisitDate, + tripItemId: number, +) => { + socketClient.publish({ + destination: `/pub/tripItems/${tripItemId}/updateVisitDate`, + body: JSON.stringify(pubUpdateVisitDate), + }); +}; + +// 여행 아이템 삭제 이벤트 발생시 +export const pubDeleteItem = (tripItemId: number) => { + socketClient.publish({ + destination: `/pub/tripItems/${tripItemId}/deleteItem`, + }); +}; + +// 멤버 여정 페이지로 입장 이벤트 발생시 +export const pubConnectMember = (pubMember: pubMember, tripId: number) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/connectMember`, + body: JSON.stringify(pubMember), + }); +}; + +// 멤버 여정 페이지 퇴장 이벤트 발생시 +export const pubDisconnectMember = (pubMember: pubMember, tripId: number) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/disconnectMember`, + body: JSON.stringify(pubMember), + }); +}; + +// 여정 편집 페이지 입장 이벤트 발생시(모든 sub 다받음) +export const pubEnterMember = (pubMember: pubMember, tripId: number) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/enterMember`, + body: JSON.stringify(pubMember), + }); +}; + +// 날짜별 여행 아이템 & 경로 조회 +export const pubGetPathAndItems = ( + pubGetPathAndItems: pubVisitDate, + tripId: number, +) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/getPathAndItems`, + body: JSON.stringify(pubGetPathAndItems), + }); +}; diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx new file mode 100644 index 00000000..864c3989 --- /dev/null +++ b/src/components/Plan/PlanItem.tsx @@ -0,0 +1,57 @@ +import { useEffect } from 'react'; +import { socketClient } from '@api/socket'; +import { + subInfo, + subItem, + subPath, + subMember, + subBudget, + pubEnterMember, +} from '@api/socket'; +import SubmitBtn from '@components/common/button/SubmitBtn'; +import { PlusIcon } from '@components/common/icons/Icons'; +import { useNavigate } from 'react-router-dom'; + +const tripId = 1; +const visitDate = '2024-01-07'; +const pubMember = { + memberId: 1, +}; + +const PlanItem = () => { + const navigate = useNavigate(); + + const socketConnect = () => { + socketClient.onConnect = () => { + subInfo(tripId); + subItem(tripId, visitDate); + subPath(tripId, visitDate); + subMember(tripId); + subBudget(tripId); + pubEnterMember(pubMember, tripId); + }; + + socketClient.activate(); + }; + + useEffect(() => { + socketConnect(); + + return () => { + socketClient.deactivate(); + }; + }, []); + + return ( + <> + navigate('./place')}> +
+ + 장소 추가 +
+
+ + ); +}; + +export default PlanItem; diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 28cb6b9d..770759c1 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -3,6 +3,7 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import TripBudget from './TripBudget'; import Tab from '@components/common/tab/Tab'; +import PlanItem from './PlanItem'; const PlanSectionTop = () => { const navigate = useNavigate(); @@ -21,6 +22,7 @@ const PlanSectionTop = () => { lists={['Day1', 'Day2', 'Day3']} contents={[
Day1
,
Day2
,
Day3
]} /> + ); }; diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index 443384c4..b1e197d5 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -425,7 +425,7 @@ export const PlusIcon: React.FC = ({ stroke={color} strokeWidth="1.5" strokeLinecap="round" - stroke-linejoin="round" + strokeLinejoin="round" /> { - socketClient.onConnect = () => { - socketClient.subscribe(`/sub/${tripId}/info`, (message) => { - console.log(`기본정보 변경 이벤트:`, message.body); - }); - - socketClient.subscribe( - `/sub/${tripId}/tripItems/${visitDate}`, - (message) => { - console.log(`방문날짜별 여정 여행 아이템 정보:`, message.body); - }, - ); - - socketClient.subscribe(`/sub/${tripId}/path/${visitDate}`, (message) => { - console.log(`방문날짜별 여정경로 정보:`, message.body); - }); - - socketClient.subscribe(`/sub/${tripId}/connectedMember`, (message) => { - console.log(`연결된 멤버 정보 :`, message.body); - }); - - socketClient.subscribe(`/sub/${tripId}/budget`, (message) => { - console.log(`목표 경비, 실제 발생 비용:`, message.body); - }); - - socketClient.publish({ - // 여정 기본 정보 변경 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/info`, - body: JSON.stringify(message), - }); - - socketClient.publish({ - // 여정에 여행 아이템 추가 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/addTripItems`, - body: JSON.stringify(itemMessage), - }); - - socketClient.publish({ - // 여행 아이템 예상 가격 업데이트 이벤트 발생시 ✅ - destination: `/pub/tripItems/${tripItemId}/updatePrice`, - body: JSON.stringify(price), - }); - - socketClient.publish({ - // 여행 아이템 방문 순서 변경 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/updateTripItemOrder`, - body: JSON.stringify(Order), - }); - - socketClient.publish({ - // 여행 아이템 방문 교통 수단 변경 이벤트 발생시 ✅ - destination: `/pub/tripItems/${tripItemId}/updateTransportation`, - body: JSON.stringify(trans), - }); - - socketClient.publish({ - // 여행 아이템 방문 날짜 변경 이벤트 발생시 ✅ - destination: `/pub/tripItems/${tripItemId}/updateVisitDate`, - body: JSON.stringify(data), - }); - - socketClient.publish({ - // 여행 아이템 삭제 이벤트 발생시 ✅ - destination: `/pub/tripItems/${tripItemId}/deleteItem`, - }); - - socketClient.publish({ - // 멤버 여정 페이지로 입장 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/connectMember`, - body: JSON.stringify(member), - }); - - socketClient.publish({ - // 멤버 여정 페이지 퇴장 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/disconnectMember`, - body: JSON.stringify(member), - }); - - socketClient.publish({ - // 여정 편집 페이지 입장 이벤트 발생시 ✅ - destination: `/pub/trips/${tripId}/enterMember`, - body: JSON.stringify(member), - }); - - socketClient.publish({ - // 날짜별 여행 아이템 & 경로 조회 ✅ - destination: `/pub/trips/${tripId}/getPathAndItems`, - body: JSON.stringify(data), - }); - }; - - socketClient.activate(); -}; - -useEffect(() => { - connect(); - - return () => { - socketClient.deactivate(); - }; -}, []); From 0b31fb3fbcfd9af03f09d7ab94024b3639a38ea9 Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 14 Jan 2024 12:46:40 +0900 Subject: [PATCH 02/16] =?UTF-8?q?Feat:=20=EC=86=8C=EC=BC=93=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=ED=95=B8=EB=93=A4=EB=A7=81,=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/service.ts | 86 ++++++++++++++++++++++++++++++ src/@types/socket.types.ts | 90 +++++++++++++++++++++++++++++++- src/api/socket.ts | 39 ++++++++++---- src/components/Plan/PlanItem.tsx | 58 +++++++++++++++++--- 4 files changed, 253 insertions(+), 20 deletions(-) create mode 100644 src/@types/service.ts diff --git a/src/@types/service.ts b/src/@types/service.ts new file mode 100644 index 00000000..e31ce9a9 --- /dev/null +++ b/src/@types/service.ts @@ -0,0 +1,86 @@ +export type subInfoRes = { + status: number; + message: string; + data: { + tripId: number; + startDate: string; + endDate: string; + numberOfPeople: number; + tripName: string; + tripStatus: string; + area: string; + subarea: string; + budget: number; + } | null; +}; + +export type subItemRes = { + status: number; + message: string; + data: { + tripId: number; + visitDate: string; + tripItems: { + tripItemId: number; + tourItemId: number; + name: string; + thumbnailUrl: string; + category: string; + transportation: string; + seqNum: number; + visitDate: string; + price: number; + }[]; + } | null; +}; + +export type subPathRes = { + status: number; + message: string; + data: { + tripId: number; + visitDate: string; + paths: { + fromSeqNum: number; + toSeqNum: number; + fromLongitude: string; + fromLatitude: string; + toLongitude: string; + toLatitude: string; + transportation: string; + pathInfo: { + price: number; + totalDistance: number; + totalTime: number; + }; + }[]; + } | null; +}; + +export type subMemberRes = { + status: number; + message: string; + data: { + tripId: number; + connectedMembers: { + memberId: number; + name: string; + thumbnailUrl: string; + }[]; + tripMembers: { + memberId: number; + name: string; + thumbnailUrl: string; + }[]; + numberOfPeople: number; + } | null; +}; +export type subBudgetRes = { + status: number; + message: string; + data: { + tripId: number; + budget: number; + calculatedPrice: number; + } | null; +}; diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index 11433be8..3634d2c4 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -37,8 +37,94 @@ interface pubUpdateTransportation { transportation: 'CAR' | 'PUBLIC_TRANSPORTATION'; } - - interface pubMember { memberId: number; } + +type subInfoMessage = (message: { + status: number; + message: string; + data: { + tripId: number; + startDate: string; + endDate: string; + numberOfPeople: number; + tripName: string; + tripStatus: string; + area: string; + subarea: string; + budget: number; + } | null; +}) => void; + +type subItemMessage = (response: { + status: number; + message: string; + data: { + tripId: number; + visitDate: string; + tripItems: { + tripItemId: number; + tourItemId: number; + name: string; + thumbnailUrl: string; + category: string; + transportation: string; + seqNum: number; + visitDate: string; + price: number; + }[]; + }; +}) => void; + +type subPathMessage = (response: { + status: number; + message: string; + data: { + tripId: number; + visitDate: string; + paths: { + fromSeqNum: number; + toSeqNum: number; + fromLongitude: string; + fromLatitude: string; + toLongitude: string; + toLatitude: string; + transportation: string; + pathInfo: { + price: number; + totalDistance: number; + totalTime: number; + }; + }[]; + }; +}) => void; + +type subMemberMessage = (response: { + status: number; + message: string; + data: { + tripId: number; + connectedMembers: { + memberId: number; + name: string; + thumbnailUrl: string; + }[]; + tripMembers: { + memberId: number; + name: string; + thumbnailUrl: string; + }[]; + numberOfPeople: number; + }; +}) => void; + +type subBudgetMessage = (response: { + status: number; + message: string; + data: { + tripId: number; + budget: number; + calculatedPrice: number; + }; +}) => void; diff --git a/src/api/socket.ts b/src/api/socket.ts index d69a9281..cd8bf767 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -6,37 +6,56 @@ export const socketClient = new StompJs.Client({ // 소켓 구독 // 여정 기본 정보 -export const subInfo = (tripId: number) => { +export const subInfo = (tripId: number, subInfoMessage: subInfoMessage) => { socketClient.subscribe(`/sub/${tripId}/info`, (message) => { - console.log(`기본정보 변경 이벤트:`, message.body); + const res = JSON.parse(message.body); + subInfoMessage(res); }); }; // 방문 날짜별 여정 여행 아이템 정보 -export const subItem = (tripId: number, visitDate: string) => { +export const subItem = ( + tripId: number, + visitDate: string, + subItemMessage: subItemMessage, +) => { socketClient.subscribe(`/sub/${tripId}/tripItems/${visitDate}`, (message) => { - console.log(`방문날짜별 여정 여행 아이템 정보:`, message.body); + const res = JSON.parse(message.body); + subItemMessage(res); }); }; // 방문 날짜별 여정 경로 정보 -export const subPath = (tripId: number, visitDate: string) => { +export const subPath = ( + tripId: number, + visitDate: string, + subPathMessage: subPathMessage, +) => { socketClient.subscribe(`/sub/${tripId}/path/${visitDate}`, (message) => { - console.log(`방문날짜별 여정경로 정보:`, message.body); + const res = JSON.parse(message.body); + subPathMessage(res); }); }; // 연결된 멤버 정보 -export const subMember = (tripId: number) => { +export const subMember = ( + tripId: number, + subMemberMessage: subMemberMessage, +) => { socketClient.subscribe(`/sub/${tripId}/connectedMember`, (message) => { - console.log(`연결된 멤버 정보 :`, message.body); + const res = JSON.parse(message.body); + subMemberMessage(res); }); }; // 목표 경비, 실제 발생 비용 -export const subBudget = (tripId: number) => { +export const subBudget = ( + tripId: number, + subBudgetMessage: subBudgetMessage, +) => { socketClient.subscribe(`/sub/${tripId}/budget`, (message) => { - console.log(`목표 경비, 실제 발생 비용:`, message.body); + const res = JSON.parse(message.body); + subBudgetMessage(res); }); }; diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 864c3989..83170af1 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { socketClient } from '@api/socket'; import { subInfo, @@ -8,12 +8,20 @@ import { subBudget, pubEnterMember, } from '@api/socket'; + +import { + subInfoRes, + subItemRes, + subPathRes, + subMemberRes, + subBudgetRes, +} from '@/@types/service'; import SubmitBtn from '@components/common/button/SubmitBtn'; import { PlusIcon } from '@components/common/icons/Icons'; import { useNavigate } from 'react-router-dom'; const tripId = 1; -const visitDate = '2024-01-07'; +const visitDate = '2024-01-03'; const pubMember = { memberId: 1, }; @@ -21,13 +29,48 @@ const pubMember = { const PlanItem = () => { const navigate = useNavigate(); + 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); + + if (tripInfo != null) { + console.log(tripInfo); + } + const socketConnect = () => { socketClient.onConnect = () => { - subInfo(tripId); - subItem(tripId, visitDate); - subPath(tripId, visitDate); - subMember(tripId); - subBudget(tripId); + subInfo(tripId, (res) => { + if (res) { + setTripInfo(res); + } + }); + + subItem(tripId, visitDate, (res) => { + if (res) { + setTripItem(res); + } + }); + + subPath(tripId, visitDate, (res) => { + if (res) { + setTripPath(res); + } + }); + + subMember(tripId, (res) => { + if (res) { + setTripMember(res); + } + }); + + subBudget(tripId, (res) => { + if (res) { + setTripBudget(res); + } + }); + pubEnterMember(pubMember, tripId); }; @@ -41,7 +84,6 @@ const PlanItem = () => { socketClient.deactivate(); }; }, []); - return ( <> navigate('./place')}> From 2d7dbad486a17781911f524c52e2915758911af4 Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 17:55:29 +0900 Subject: [PATCH 03/16] =?UTF-8?q?Feat:=20=EC=97=AC=ED=96=89=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/create/createTrip.page.tsx | 31 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index 7a35c568..b5ca64a3 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -14,6 +14,7 @@ import { ko } from 'date-fns/locale'; import { useState } from 'react'; import { useRecoilValue } from 'recoil'; import { SelectDate } from '../../components/createTrip/SelectDate'; +import { postTrips } from '@api/trips'; export const CreateTrip = () => { const [title, setTitle] = useState(''); @@ -21,6 +22,27 @@ export const CreateTrip = () => { const [showSelectDate, setShowSelectDate] = useState(false); const [showSelectDestination, setShowSelectDestination] = useState(false); + const handleSubmit = async () => { + try { + const tripRequestData = { + tripName: title || '나의 N번째 여정', // title이 빈 문자열일 경우 기본값 설정 + numberOfPeople: numOfMembers, + startDate: tripDate.startDate + ? tripDate.startDate.toISOString().split('T')[0] + : null, + endDate: tripDate.endDate + ? tripDate.endDate.toISOString().split('T')[0] + : null, + }; + + const response = await postTrips(tripRequestData); + console.log('전송 완료: ', response); + // 리코일 초기화 + } catch (error) { + console.error('전송 실패: ', error); + } + }; + const handleIncrease = () => { setNumOfMembers((prevNum) => prevNum + 1); }; @@ -32,11 +54,8 @@ export const CreateTrip = () => { const tripDate = useRecoilValue(tripDateState); const formattedTripDate = tripDate.startDate && tripDate.endDate - ? `${format(tripDate.startDate, 'MM.dd', { locale: ko })} - ${format( - tripDate.endDate, - 'MM.dd', - { locale: ko }, - )}` + ? `${format(tripDate.startDate, 'MM.dd', { locale: ko })} - + ${format(tripDate.endDate, 'MM.dd', { locale: ko })}` : '여행 날짜(선택)'; if (showSelectDate) { @@ -119,7 +138,7 @@ export const CreateTrip = () => {
- {}}>완료 + 완료
); From a591dea428c5cf12cdd872bd550b0695d59ce947 Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 18:26:09 +0900 Subject: [PATCH 04/16] =?UTF-8?q?Fix:=20api=20authClient=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/trips.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/trips.ts b/src/api/trips.ts index 7d7aeb81..3cb10b13 100644 --- a/src/api/trips.ts +++ b/src/api/trips.ts @@ -1,4 +1,5 @@ import client from './client'; +import authClient from './authClient'; // 여정 관련 API @@ -22,7 +23,7 @@ export const deleteTrips = async (tripId: number) => { // 여정 생성 export const postTrips = async (tripsData: TripRequest) => { - const res = await client.post(`trips`, tripsData); + const res = await authClient.post(`trips`, tripsData); return res; }; From 7c4a4caa8192db98738f3dc9c9a60d01670f1204 Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 19:02:16 +0900 Subject: [PATCH 05/16] =?UTF-8?q?Refactor:=20hook,=20utils=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/trips.types.ts | 8 +++---- src/hooks/useCounter.ts | 21 +++++++++++++++++++ src/pages/create/createTrip.page.tsx | 31 ++++++++++++++-------------- src/utils/formatDate.ts | 9 ++++++++ 4 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 src/hooks/useCounter.ts create mode 100644 src/utils/formatDate.ts diff --git a/src/@types/trips.types.ts b/src/@types/trips.types.ts index cda8b28b..1130cab9 100644 --- a/src/@types/trips.types.ts +++ b/src/@types/trips.types.ts @@ -1,8 +1,8 @@ interface TripRequest { tripName: string; numberOfPeople: number; - startDate: string; - endDate: string; - area: string; - subarea: string; + startDate: string | null; + endDate: string | null; + area: string | null; + subarea: string | null; } diff --git a/src/hooks/useCounter.ts b/src/hooks/useCounter.ts new file mode 100644 index 00000000..4ff26ba9 --- /dev/null +++ b/src/hooks/useCounter.ts @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +const useCounter = ( + initialValue: number = 0, + min: number = 0, + max: number = Infinity, +): [number, () => void, () => void] => { + const [value, setValue] = useState(initialValue); + + const increase = () => { + setValue((prevValue) => Math.min(prevValue + 1, max)); + }; + + const decrease = () => { + setValue((prevValue) => Math.max(prevValue - 1, min)); + }; + + return [value, increase, decrease]; +}; + +export default useCounter; diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index b5ca64a3..4ddc2fe8 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -9,16 +9,20 @@ import { import { InputField } from '@components/createTrip/InputField'; import { SelectDestination } from '@components/createTrip/SelectDestination'; import { tripDateState } from '@recoil/tripDate'; -import { format } from 'date-fns'; -import { ko } from 'date-fns/locale'; import { useState } from 'react'; import { useRecoilValue } from 'recoil'; import { SelectDate } from '../../components/createTrip/SelectDate'; import { postTrips } from '@api/trips'; +import useCounter from '@hooks/useCounter'; +import { formatDate } from '@utils/formatDate'; export const CreateTrip = () => { const [title, setTitle] = useState(''); - const [numOfMembers, setNumOfMembers] = useState(2); + const [numOfMembers, increaseNumOfMembers, decreaseNumOfMembers] = useCounter( + 2, + 2, + 12, + ); // (기본값, 최솟값, 최댓값) const [showSelectDate, setShowSelectDate] = useState(false); const [showSelectDestination, setShowSelectDestination] = useState(false); @@ -33,29 +37,24 @@ export const CreateTrip = () => { endDate: tripDate.endDate ? tripDate.endDate.toISOString().split('T')[0] : null, + area: null, + subarea: null, }; const response = await postTrips(tripRequestData); console.log('전송 완료: ', response); - // 리코일 초기화 } catch (error) { console.error('전송 실패: ', error); } }; - const handleIncrease = () => { - setNumOfMembers((prevNum) => prevNum + 1); - }; - - const handleDecrease = () => { - setNumOfMembers((prevNum) => Math.max(prevNum - 1, 2)); - }; - const tripDate = useRecoilValue(tripDateState); const formattedTripDate = tripDate.startDate && tripDate.endDate - ? `${format(tripDate.startDate, 'MM.dd', { locale: ko })} - - ${format(tripDate.endDate, 'MM.dd', { locale: ko })}` + ? `${formatDate(tripDate.startDate, 'MM.dd')} - ${formatDate( + tripDate.endDate, + 'MM.dd', + )}` : '여행 날짜(선택)'; if (showSelectDate) { @@ -108,12 +107,12 @@ export const CreateTrip = () => {
diff --git a/src/utils/formatDate.ts b/src/utils/formatDate.ts new file mode 100644 index 00000000..2e5a2d5b --- /dev/null +++ b/src/utils/formatDate.ts @@ -0,0 +1,9 @@ +import { format } from 'date-fns'; +import { ko } from 'date-fns/locale'; + +export const formatDate = ( + date: Date | number, + dateFormat: string, +): string | null => { + return date ? format(date, dateFormat, { locale: ko }) : null; +}; From 188656c118073da39f128d1dcd6186bf58e1085f Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 19:42:02 +0900 Subject: [PATCH 06/16] =?UTF-8?q?Feat:=20=EB=82=98=EC=9D=98=EC=97=AC?= =?UTF-8?q?=EC=A0=95=20=EB=94=94=ED=8F=B4=ED=8A=B8=20=ED=83=80=EC=9D=B4?= =?UTF-8?q?=ED=8B=80=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/member.ts | 10 +++++++--- src/pages/create/createTrip.page.tsx | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/api/member.ts b/src/api/member.ts index 1e355324..e7c702de 100644 --- a/src/api/member.ts +++ b/src/api/member.ts @@ -44,9 +44,13 @@ export const deleteMember = async () => { }; // 나의 여정 조회 -export const getMemberTrips = async () => { - const res = await authClient.get(`member/trips`); - return res; +export const getMemberTrips = async (page = 0, size = 10) => { + try { + const res = await authClient.get(`trips?&page=${page}&size=${size}`); + return res.data; + } catch (e) { + console.error(e); + } }; // 나의 관심 여행지 조회 diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index 4ddc2fe8..1d9a4883 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -15,6 +15,8 @@ import { SelectDate } from '../../components/createTrip/SelectDate'; import { postTrips } from '@api/trips'; import useCounter from '@hooks/useCounter'; import { formatDate } from '@utils/formatDate'; +import { useQuery } from '@tanstack/react-query'; +import { getMemberTrips } from '@api/member'; export const CreateTrip = () => { const [title, setTitle] = useState(''); @@ -26,10 +28,18 @@ export const CreateTrip = () => { const [showSelectDate, setShowSelectDate] = useState(false); const [showSelectDestination, setShowSelectDestination] = useState(false); + const { data } = useQuery({ + queryKey: ['myTrips'], + queryFn: () => getMemberTrips(), + }); + + const MY_TRIP_NUMBER = data?.data.numberOfElements + 1; + const defaultTitle = `나의 여정 ${MY_TRIP_NUMBER}`; + const handleSubmit = async () => { try { const tripRequestData = { - tripName: title || '나의 N번째 여정', // title이 빈 문자열일 경우 기본값 설정 + tripName: title || defaultTitle, numberOfPeople: numOfMembers, startDate: tripDate.startDate ? tripDate.startDate.toISOString().split('T')[0] @@ -84,7 +94,7 @@ export const CreateTrip = () => { { setTitle(e.target.value); From a69cad6757164101f308b2a27a8ab396e10c2188 Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 20:37:17 +0900 Subject: [PATCH 07/16] =?UTF-8?q?Style:=20=EC=9D=BC=EC=A0=95=20=EC=A4=91?= =?UTF-8?q?=EA=B0=84=EB=82=A0=EC=A7=9C=20=EC=8A=A4=ED=83=80=EC=9D=BC?= =?UTF-8?q?=EB=A7=81=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DatePicker/Calendar.tsx | 50 ++++++++++++-------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/components/DatePicker/Calendar.tsx b/src/components/DatePicker/Calendar.tsx index 0c317d68..5185160e 100644 --- a/src/components/DatePicker/Calendar.tsx +++ b/src/components/DatePicker/Calendar.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; import { - addDays, addMonths, differenceInDays, format, @@ -8,13 +7,11 @@ import { isSameDay, isWithinInterval, startOfMonth, - subDays, } from 'date-fns'; import { ko } from 'date-fns/locale'; import 'tailwindcss/tailwind.css'; const CALENDAR_LENGTH = 42; -// const DAY_OF_WEEK = 7; const DAY_LIST = ['일', '월', '화', '수', '목', '금', '토']; const Calendar: React.FC<{ @@ -52,7 +49,10 @@ const Calendar: React.FC<{ }; const handleDateClick = (date: Date) => { - if (!startDate || (startDate && endDate)) { + if (startDate && !endDate && date < startDate) { + setEndDate(startDate); + setStartDate(date); + } else if (!startDate || (startDate && endDate)) { setStartDate(date); setEndDate(null); } else if (date > startDate) { @@ -78,7 +78,9 @@ const Calendar: React.FC<{ const renderDayLabels = () => { return DAY_LIST.map((dayLabel, index) => ( -
+
{dayLabel}
)); @@ -95,16 +97,17 @@ const Calendar: React.FC<{ let beforeClass = ''; let afterClass = ''; - if (isStart || isEnd) { - dayClass = 'rounded-full w-[48px] bg-main2 text-white z-10'; - } else if (isMiddle) { - dayClass = 'bg-[#DAFBFF] z-0'; - beforeClass = isSecondDayInRange(date) - ? 'before:content-[""] before:absolute before:left-[-50%] before:top-0 before:w-1/2 before:h-full before:bg-[#DAFBFF]' - : ''; - afterClass = isSecondLastDayInRange(date) - ? 'after:content-[""] after:absolute after:right-[-50%] after:top-0 after:w-1/2 after:h-full after:bg-[#DAFBFF]' + if (isStart) { + dayClass = 'rounded-full w-[40px] bg-main2 text-white z-10'; + afterClass = endDate + ? 'after:content-[""] after:absolute after:left-[50%] after:top-[4px] after:w-[32px] after:h-[40px] after:bg-[#DAFBFF] after:z-[1]' : ''; + } else if (isEnd) { + dayClass = 'rounded-full w-[40px] bg-main2 text-white z-10'; + beforeClass = + 'before:content-[""] before:absolute before:right-[50%] before:top-[4px] before:w-[32px] before:h-[40px] before:bg-[#DAFBFF] before:z-[1]'; + } else if (isMiddle) { + dayClass = 'bg-[#DAFBFF]'; } const onClick = () => handleDateClick(date); @@ -112,25 +115,16 @@ const Calendar: React.FC<{ return (
- {day} +
+ {day} +
); }; - const isSecondDayInRange = (date: Date) => { - if (!startDate || !endDate) return false; - const nextDay = addDays(startDate, 1); - return isSameDay(date, nextDay); - }; - - const isSecondLastDayInRange = (date: Date) => { - if (!startDate || !endDate) return false; - const prevDay = subDays(endDate, 1); - return isSameDay(date, prevDay); - }; - const renderCalendar = (monthDate: Date) => { const totalMonthDays = getDaysInMonth(monthDate); const startDay = startOfMonth(monthDate).getDay(); From 8860874d8c960d552b75ed441a057fbe02f6e8e9 Mon Sep 17 00:00:00 2001 From: joanShim Date: Sun, 14 Jan 2024 20:41:41 +0900 Subject: [PATCH 08/16] =?UTF-8?q?Feat:=20=EC=83=9D=EC=84=B1=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20=ED=9B=84=20=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/create/createTrip.page.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/create/createTrip.page.tsx b/src/pages/create/createTrip.page.tsx index 1d9a4883..c9e2b865 100644 --- a/src/pages/create/createTrip.page.tsx +++ b/src/pages/create/createTrip.page.tsx @@ -17,8 +17,10 @@ import useCounter from '@hooks/useCounter'; import { formatDate } from '@utils/formatDate'; import { useQuery } from '@tanstack/react-query'; import { getMemberTrips } from '@api/member'; +import { useNavigate } from 'react-router-dom'; export const CreateTrip = () => { + const navigate = useNavigate(); const [title, setTitle] = useState(''); const [numOfMembers, increaseNumOfMembers, decreaseNumOfMembers] = useCounter( 2, @@ -53,6 +55,8 @@ export const CreateTrip = () => { const response = await postTrips(tripRequestData); console.log('전송 완료: ', response); + const tripId = response.data.data.tripId; + navigate('/trip/' + tripId); } catch (error) { console.error('전송 실패: ', error); } From 4e27050273a586230e9092337bd59f8d7f708e7e Mon Sep 17 00:00:00 2001 From: Hojin Date: Sun, 14 Jan 2024 23:51:45 +0900 Subject: [PATCH 09/16] =?UTF-8?q?Feat:=20=EC=86=8C=EC=BC=93=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=ED=9B=85=20=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 | 32 ++++++--- src/api/socket.ts | 26 +++---- src/components/Plan/PlanItem.tsx | 91 +++++------------------- src/components/Plan/PlanItemBox.tsx | 37 ++++++++++ src/components/Plan/PlanSectionTop.tsx | 8 ++- src/hooks/useSocket.ts | 96 ++++++++++++++++++++++++++ src/pages/main/main.page.tsx | 28 -------- src/recoil/socket.ts | 11 +++ src/router/socketRouter.tsx | 46 ++++++++---- 9 files changed, 231 insertions(+), 144 deletions(-) create mode 100644 src/components/Plan/PlanItemBox.tsx create mode 100644 src/hooks/useSocket.ts create mode 100644 src/recoil/socket.ts diff --git a/src/@types/service.ts b/src/@types/service.ts index e31ce9a9..ebbfa424 100644 --- a/src/@types/service.ts +++ b/src/@types/service.ts @@ -20,20 +20,22 @@ export type subItemRes = { data: { tripId: number; visitDate: string; - tripItems: { - tripItemId: number; - tourItemId: number; - name: string; - thumbnailUrl: string; - category: string; - transportation: string; - seqNum: number; - visitDate: string; - price: number; - }[]; + tripItems: TripItem[]; } | null; }; +export type TripItem = { + tripItemId: number; + tourItemId: number; + name: string; + thumbnailUrl: string; + category: string; + transportation: string; + seqNum: number; + visitDate: string; + price: number; +}; + export type subPathRes = { status: number; message: string; @@ -84,3 +86,11 @@ export type subBudgetRes = { calculatedPrice: number; } | null; }; + +export type SocketContextType = { + tripInfo: subInfoRes | null; + tripItem: subItemRes | null; + tripPath: subPathRes | null; + tripMember: subMemberRes | null; + tripBudget: subBudgetRes | null; +}; diff --git a/src/api/socket.ts b/src/api/socket.ts index cd8bf767..b24503c0 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -6,7 +6,7 @@ export const socketClient = new StompJs.Client({ // 소켓 구독 // 여정 기본 정보 -export const subInfo = (tripId: number, subInfoMessage: subInfoMessage) => { +export const subInfo = (tripId: string, subInfoMessage: subInfoMessage) => { socketClient.subscribe(`/sub/${tripId}/info`, (message) => { const res = JSON.parse(message.body); subInfoMessage(res); @@ -15,7 +15,7 @@ export const subInfo = (tripId: number, subInfoMessage: subInfoMessage) => { // 방문 날짜별 여정 여행 아이템 정보 export const subItem = ( - tripId: number, + tripId: string, visitDate: string, subItemMessage: subItemMessage, ) => { @@ -27,7 +27,7 @@ export const subItem = ( // 방문 날짜별 여정 경로 정보 export const subPath = ( - tripId: number, + tripId: string, visitDate: string, subPathMessage: subPathMessage, ) => { @@ -39,7 +39,7 @@ export const subPath = ( // 연결된 멤버 정보 export const subMember = ( - tripId: number, + tripId: string, subMemberMessage: subMemberMessage, ) => { socketClient.subscribe(`/sub/${tripId}/connectedMember`, (message) => { @@ -50,7 +50,7 @@ export const subMember = ( // 목표 경비, 실제 발생 비용 export const subBudget = ( - tripId: number, + tripId: string, subBudgetMessage: subBudgetMessage, ) => { socketClient.subscribe(`/sub/${tripId}/budget`, (message) => { @@ -61,7 +61,7 @@ export const subBudget = ( // 소켓 전송 // 여정 기본 정보 변경 이벤트 발생시 -export const pubInfo = (pubInfo: pubInfo, tripId: number) => { +export const pubInfo = (pubInfo: pubInfo, tripId: string) => { socketClient.publish({ destination: `/pub/trips/${tripId}/info`, body: JSON.stringify(pubInfo), @@ -71,7 +71,7 @@ export const pubInfo = (pubInfo: pubInfo, tripId: number) => { // 여정에 여행 아이템 추가 이벤트 발생시 export const pubAddTripItem = ( pubAddTripItem: pubAddTripItem, - tripId: number, + tripId: string, ) => { socketClient.publish({ destination: `/pub/trips/${tripId}/addTripItems`, @@ -82,7 +82,7 @@ export const pubAddTripItem = ( // 여행 아이템 예상 가격 업데이트 이벤트 발생시 export const pubUpdatePrice = ( pubUpdatePrice: pubUpdatePrice, - tripItemId: number, + tripItemId: string, ) => { socketClient.publish({ destination: `/pub/tripItems/${tripItemId}/updatePrice`, @@ -93,7 +93,7 @@ export const pubUpdatePrice = ( // 여행 아이템 방문 순서 변경 이벤트 발생시 export const pubUpdateTripItem = ( pubUpdateTripItem: pubUpdateTripItem, - tripId: number, + tripId: string, ) => { socketClient.publish({ destination: `/pub/trips/${tripId}/updateTripItemOrder`, @@ -131,7 +131,7 @@ export const pubDeleteItem = (tripItemId: number) => { }; // 멤버 여정 페이지로 입장 이벤트 발생시 -export const pubConnectMember = (pubMember: pubMember, tripId: number) => { +export const pubConnectMember = (pubMember: pubMember, tripId: string) => { socketClient.publish({ destination: `/pub/trips/${tripId}/connectMember`, body: JSON.stringify(pubMember), @@ -139,7 +139,7 @@ export const pubConnectMember = (pubMember: pubMember, tripId: number) => { }; // 멤버 여정 페이지 퇴장 이벤트 발생시 -export const pubDisconnectMember = (pubMember: pubMember, tripId: number) => { +export const pubDisconnectMember = (pubMember: pubMember, tripId: string) => { socketClient.publish({ destination: `/pub/trips/${tripId}/disconnectMember`, body: JSON.stringify(pubMember), @@ -147,7 +147,7 @@ export const pubDisconnectMember = (pubMember: pubMember, tripId: number) => { }; // 여정 편집 페이지 입장 이벤트 발생시(모든 sub 다받음) -export const pubEnterMember = (pubMember: pubMember, tripId: number) => { +export const pubEnterMember = (pubMember: pubMember, tripId: string) => { socketClient.publish({ destination: `/pub/trips/${tripId}/enterMember`, body: JSON.stringify(pubMember), @@ -157,7 +157,7 @@ export const pubEnterMember = (pubMember: pubMember, tripId: number) => { // 날짜별 여행 아이템 & 경로 조회 export const pubGetPathAndItems = ( pubGetPathAndItems: pubVisitDate, - tripId: number, + tripId: string, ) => { socketClient.publish({ destination: `/pub/trips/${tripId}/getPathAndItems`, diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 83170af1..3cf562b8 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -1,91 +1,32 @@ -import { useState, useEffect } from 'react'; -import { socketClient } from '@api/socket'; -import { - subInfo, - subItem, - subPath, - subMember, - subBudget, - pubEnterMember, -} from '@api/socket'; - -import { - subInfoRes, - subItemRes, - subPathRes, - subMemberRes, - subBudgetRes, -} from '@/@types/service'; import SubmitBtn from '@components/common/button/SubmitBtn'; -import { PlusIcon } from '@components/common/icons/Icons'; +import { PlusIcon, CarIcon, BusIcon } from '@components/common/icons/Icons'; import { useNavigate } from 'react-router-dom'; +import PlanItemBox from './PlanItemBox'; +import { useContext } from 'react'; +import { socketContext } from '@hooks/useSocket'; +import { pubEnterMember } from '@api/socket'; -const tripId = 1; -const visitDate = '2024-01-03'; -const pubMember = { +const memberId = { memberId: 1, }; +const visitDate = '2024-01-04'; const PlanItem = () => { const navigate = useNavigate(); + const { tripItem } = useContext(socketContext); - 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); - - if (tripInfo != null) { - console.log(tripInfo); - } - - const socketConnect = () => { - socketClient.onConnect = () => { - subInfo(tripId, (res) => { - if (res) { - setTripInfo(res); - } - }); - - subItem(tripId, visitDate, (res) => { - if (res) { - setTripItem(res); - } - }); - - subPath(tripId, visitDate, (res) => { - if (res) { - setTripPath(res); - } - }); - - subMember(tripId, (res) => { - if (res) { - setTripMember(res); - } - }); - - subBudget(tripId, (res) => { - if (res) { - setTripBudget(res); - } - }); - - pubEnterMember(pubMember, tripId); - }; - - socketClient.activate(); - }; + // console.log(tripItem); - useEffect(() => { - socketConnect(); + // pubEnterMember(memberId, visitDate); + // console.log('펍후', tripItem); - return () => { - socketClient.deactivate(); - }; - }, []); return ( <> +
+ {tripItem?.data?.tripItems.map((item) => ( + + ))} +
navigate('./place')}>
diff --git a/src/components/Plan/PlanItemBox.tsx b/src/components/Plan/PlanItemBox.tsx new file mode 100644 index 00000000..d0f8e1cf --- /dev/null +++ b/src/components/Plan/PlanItemBox.tsx @@ -0,0 +1,37 @@ +import { PenIcon } from '@components/common/icons/Icons'; +import { TripItem } from '@/@types/service'; + +type PlanItemBoxProps = { + item: TripItem; +}; + +const PlanItemBox = ({ item }: PlanItemBoxProps) => { + return ( + <> +
+
+ img +
+
+ {item.name} + +
+ +
+ {item.category} +
+
+ {item.price} 원 +
+
+
+
+ + ); +}; + +export default PlanItemBox; diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 770759c1..acfdc935 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -3,7 +3,9 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import TripBudget from './TripBudget'; import Tab from '@components/common/tab/Tab'; -import PlanItem from './PlanItem'; +import React, { Suspense } from 'react'; + +const PlanItem = React.lazy(() => import('./PlanItem')); const PlanSectionTop = () => { const navigate = useNavigate(); @@ -22,7 +24,9 @@ const PlanSectionTop = () => { lists={['Day1', 'Day2', 'Day3']} contents={[
Day1
,
Day2
,
Day3
]} /> - + + +
); }; diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts new file mode 100644 index 00000000..9246c338 --- /dev/null +++ b/src/hooks/useSocket.ts @@ -0,0 +1,96 @@ +import { + socketClient, + subInfo, + subItem, + subPath, + subMember, + subBudget, + pubEnterMember, +} from '@api/socket'; +import { + subInfoRes, + subItemRes, + subPathRes, + subMemberRes, + subBudgetRes, + SocketContextType, +} from '@/@types/service'; +import { createContext } from 'react'; +import { useState, useEffect } from 'react'; + +export const socketContext = createContext({ + tripInfo: null, + tripItem: null, + tripPath: null, + tripMember: null, + tripBudget: null, +}); + +const tripId = '1'; +const visitDate = '2024-01-03'; + +export const useSocket = () => { + 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 socketConnect = () => { + socketClient.onConnect = () => { + subInfo(tripId, (res) => { + if (res) { + setTripInfo(res); + } + }); + + subItem(tripId, visitDate, (res) => { + if (res) { + setTripItem(res); + } + }); + + subPath(tripId, visitDate, (res) => { + if (res) { + setTripPath(res); + } + }); + + subMember(tripId, (res) => { + if (res) { + setTripMember(res); + } + }); + + subBudget(tripId, (res) => { + if (res) { + setTripBudget(res); + } + }); + const memberId = { + memberId: 1, + }; + + pubEnterMember(memberId, visitDate); + + console.log(tripInfo); + console.log(tripItem); + console.log(tripPath); + console.log(tripMember); + console.log(tripBudget); + }; + + socketClient.activate(); + console.log('소켓연결'); + }; + + useEffect(() => { + socketConnect(); + return () => { + socketClient.deactivate(); + console.log('소켓연결해제'); + }; + }, []); + + return { tripInfo, tripItem, tripPath, tripMember, tripBudget }; +}; diff --git a/src/pages/main/main.page.tsx b/src/pages/main/main.page.tsx index fe7d924f..146d7d0a 100644 --- a/src/pages/main/main.page.tsx +++ b/src/pages/main/main.page.tsx @@ -1,36 +1,8 @@ import CreateTripButton from '@components/Tours/CreateTripButton'; import ToursSectionTop from '@components/Tours/ToursSectionTop'; import { StartSearchButton } from '@components/search/StartSearchBtn'; -import { useEffect } from 'react'; -import { socketClient } from '@api/socket'; - -const message = { - memberId: '제발되라', -}; const Main = () => { - const connect = () => { - console.log('시작'); - socketClient.onConnect = () => { - console.log('소켓 연결됨'); - - socketClient.subscribe('ws-stomp', (message) => { - console.log('받은 메시지:', message.body); - }); - - socketClient.publish({ - destination: 'ws-stomp', - body: JSON.stringify(message), - }); - }; - - socketClient.activate(); - }; - - useEffect(() => { - connect(); - }, []); - return ( <> diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts new file mode 100644 index 00000000..343bb402 --- /dev/null +++ b/src/recoil/socket.ts @@ -0,0 +1,11 @@ +import { atom } from 'recoil'; + +export const tripIdState = atom({ + key: 'tripIdState', + default: null, +}); + +export const visitDateState = atom({ + key: 'visitDateState', + default: null, +}); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 884179db..c2fd6dfd 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -1,25 +1,41 @@ -import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; -import PlanPlaceTrip from '@pages/plan/planPlaceTrip.page'; +import { Route, Routes } from 'react-router-dom'; +import { useSocket, socketContext } from '@hooks/useSocket'; import PlanTrip from '@pages/plan/planTrip.page'; +import PlanPlaceTrip from '@pages/plan/planPlaceTrip.page'; +import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; -import { Route, Routes } from 'react-router-dom'; import MainLayout from './routerLayout'; +// import { useParams } from 'react-router-dom'; + +const SocketRoutes = () => { + // const { id: tripId } = useParams(); + + // if (!tripId) { + // return
error
; + // } + + // const tripId = 1; + // const visitDate = '2024-01-04'; -const SocketRouter = () => { return ( - <> + - }> - } /> - } /> - } /> - } - /> - + } /> + } /> + } /> - + + ); +}; + +const SocketRouter = () => { + return ( + + }> + } /> + } /> + + ); }; From af19a4b3e60896c4354978e5321481b42bd4599e Mon Sep 17 00:00:00 2001 From: Hojin Date: Mon, 15 Jan 2024 03:08:08 +0900 Subject: [PATCH 10/16] =?UTF-8?q?Feat:=20=EC=86=8C=EC=BC=93=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=ED=9B=85=20=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 | 1 + src/components/Plan/PlanItem.tsx | 12 ++----- src/components/Plan/PlanSectionTop.tsx | 31 ++++++++++++++++--- src/hooks/useSocket.ts | 43 ++++++++++++++++---------- src/recoil/socket.ts | 5 +++ src/router/socketRouter.tsx | 24 +++++++++----- 6 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/@types/service.ts b/src/@types/service.ts index ebbfa424..9651b8f2 100644 --- a/src/@types/service.ts +++ b/src/@types/service.ts @@ -93,4 +93,5 @@ export type SocketContextType = { tripPath: subPathRes | null; tripMember: subMemberRes | null; tripBudget: subBudgetRes | null; + callBackPub: (callback: () => void) => void; }; diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 3cf562b8..f660e424 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -4,22 +4,14 @@ import { useNavigate } from 'react-router-dom'; import PlanItemBox from './PlanItemBox'; import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; -import { pubEnterMember } from '@api/socket'; -const memberId = { - memberId: 1, -}; -const visitDate = '2024-01-04'; + +const tripId = '1'; const PlanItem = () => { const navigate = useNavigate(); const { tripItem } = useContext(socketContext); - // console.log(tripItem); - - // pubEnterMember(memberId, visitDate); - // console.log('펍후', tripItem); - return ( <>
diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index acfdc935..77bf4f30 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -3,12 +3,34 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import TripBudget from './TripBudget'; import Tab from '@components/common/tab/Tab'; -import React, { Suspense } from 'react'; +import { pubEnterMember, pubConnectMember } from '@api/socket'; +import { useEffect } from 'react'; +import PlanItem from './PlanItem'; +import { useContext } from 'react'; +import { socketContext } from '@hooks/useSocket'; -const PlanItem = React.lazy(() => import('./PlanItem')); +const tripId = '1'; +const pubMember = { + memberId: 1, // 예시 값 +}; +const visitDate = { visitDate: '2024-01-03' }; const PlanSectionTop = () => { const navigate = useNavigate(); + + const { callBackPub, tripInfo, tripItem, tripPath, tripMember, tripBudget } = + useContext(socketContext); + + useEffect(() => { + callBackPub(() => pubEnterMember(pubMember, tripId)); + }, []); + + // console.log(tripInfo); + // console.log(tripItem); + // console.log(tripPath); + // console.log(tripMember); + // console.log(tripBudget); + return (
{ lists={['Day1', 'Day2', 'Day3']} contents={[
Day1
,
Day2
,
Day3
]} /> - - - + +
); }; diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 9246c338..022c6563 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -5,7 +5,6 @@ import { subPath, subMember, subBudget, - pubEnterMember, } from '@api/socket'; import { subInfoRes, @@ -24,18 +23,22 @@ export const socketContext = createContext({ tripPath: null, tripMember: null, tripBudget: null, + callBackPub: () => {}, }); -const tripId = '1'; -const visitDate = '2024-01-03'; - -export const useSocket = () => { +export const useSocket = (tripId: string, visitDate: string) => { 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); + let socketCallback: (() => void) | null = null; + + const callBackPub = (callback: () => void): void => { + socketCallback = callback; + }; + const socketConnect = () => { socketClient.onConnect = () => { subInfo(tripId, (res) => { @@ -67,17 +70,10 @@ export const useSocket = () => { setTripBudget(res); } }); - const memberId = { - memberId: 1, - }; - pubEnterMember(memberId, visitDate); - - console.log(tripInfo); - console.log(tripItem); - console.log(tripPath); - console.log(tripMember); - console.log(tripBudget); + if (socketCallback) { + socketCallback(); + } }; socketClient.activate(); @@ -92,5 +88,20 @@ export const useSocket = () => { }; }, []); - return { tripInfo, tripItem, tripPath, tripMember, tripBudget }; + return { tripInfo, tripItem, tripPath, tripMember, tripBudget, callBackPub }; }; + +// // 콜백들을 저장할 배열 +// let socketCallbacks = []; + +// // 콜백을 배열에 추가하는 함수 +// const callBackPub = (callback) => { +// socketCallbacks.push(callback); +// }; + +// // 모든 콜백을 실행하는 함수 +// const executeCallbacks = () => { +// socketCallbacks.forEach(callback => { +// callback(); +// }); +// }; diff --git a/src/recoil/socket.ts b/src/recoil/socket.ts index 343bb402..44948808 100644 --- a/src/recoil/socket.ts +++ b/src/recoil/socket.ts @@ -9,3 +9,8 @@ export const visitDateState = atom({ key: 'visitDateState', default: null, }); + +export const memberIdState = atom({ + key: 'memberIdState', + default: null, +}); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index c2fd6dfd..47fd4b29 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -5,20 +5,28 @@ import PlanPlaceTrip from '@pages/plan/planPlaceTrip.page'; import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; -// import { useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; +import { useRecoilState, useRecoilValue } from 'recoil'; +import { tripIdState } from '@recoil/socket'; +import { useEffect } from 'react'; const SocketRoutes = () => { - // const { id: tripId } = useParams(); + const { id: tripId } = useParams(); + const [currentTripId, setCurrentTripId] = useRecoilState(tripIdState); - // if (!tripId) { - // return
error
; - // } + useEffect(() => { + if (tripId) { + setCurrentTripId(tripId); + } + }, [tripId]); - // const tripId = 1; - // const visitDate = '2024-01-04'; + const visitDate = null; return ( - + } /> } /> From 1ae09d8b5e0fe1328b6d1d1b5699624687a51a9d Mon Sep 17 00:00:00 2001 From: Hojin Date: Mon, 15 Jan 2024 15:35:00 +0900 Subject: [PATCH 11/16] =?UTF-8?q?Feat:=20=EC=9B=B9=EC=86=8C=EC=BC=93=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=A6=AC=EC=BD=94?= =?UTF-8?q?=EC=9D=BC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Plan/PlanItem.tsx | 19 +++++++++++++++---- src/components/Plan/PlanSectionTop.tsx | 23 ----------------------- src/recoil/socket.ts | 10 +++++----- src/router/socketRouter.tsx | 23 ++++++++--------------- 4 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index f660e424..257a8e32 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -4,13 +4,24 @@ import { useNavigate } from 'react-router-dom'; import PlanItemBox from './PlanItemBox'; import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; - - -const tripId = '1'; +import { pubEnterMember } from '@api/socket'; +import { useEffect } from 'react'; +import { useRecoilValue, useRecoilState } from 'recoil'; +import { tripIdState, memberIdState } from '@recoil/socket'; const PlanItem = () => { const navigate = useNavigate(); - const { tripItem } = useContext(socketContext); + const tripId = useRecoilValue(tripIdState); + const pubMember = useRecoilValue(memberIdState); + const { callBackPub, tripItem } = useContext(socketContext); + + if (!pubMember || !tripId) { + return
에러
; + } + + useEffect(() => { + callBackPub(() => pubEnterMember(pubMember, tripId)); + }, []); return ( <> diff --git a/src/components/Plan/PlanSectionTop.tsx b/src/components/Plan/PlanSectionTop.tsx index 77bf4f30..d034b0f1 100644 --- a/src/components/Plan/PlanSectionTop.tsx +++ b/src/components/Plan/PlanSectionTop.tsx @@ -3,34 +3,11 @@ import { BackBox } from '@components/common'; import { useNavigate } from 'react-router-dom'; import TripBudget from './TripBudget'; import Tab from '@components/common/tab/Tab'; -import { pubEnterMember, pubConnectMember } from '@api/socket'; -import { useEffect } from 'react'; import PlanItem from './PlanItem'; -import { useContext } from 'react'; -import { socketContext } from '@hooks/useSocket'; - -const tripId = '1'; -const pubMember = { - memberId: 1, // 예시 값 -}; -const visitDate = { visitDate: '2024-01-03' }; const PlanSectionTop = () => { const navigate = useNavigate(); - const { callBackPub, tripInfo, tripItem, tripPath, tripMember, tripBudget } = - useContext(socketContext); - - useEffect(() => { - callBackPub(() => pubEnterMember(pubMember, tripId)); - }, []); - - // console.log(tripInfo); - // console.log(tripItem); - // console.log(tripPath); - // console.log(tripMember); - // console.log(tripBudget); - return (
({ key: 'tripIdState', - default: null, + default: '1', }); -export const visitDateState = atom({ +export const visitDateState = atom<{ visitDate: string } | null>({ key: 'visitDateState', - default: null, + default: { visitDate: '2024-01-03' }, }); -export const memberIdState = atom({ +export const memberIdState = atom<{ memberId: number } | null>({ key: 'memberIdState', - default: null, + default: { memberId: 1 }, }); diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 47fd4b29..4f39b3c5 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -6,27 +6,20 @@ import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; import { useParams } from 'react-router-dom'; -import { useRecoilState, useRecoilValue } from 'recoil'; -import { tripIdState } from '@recoil/socket'; +import { useRecoilValue, useRecoilState } from 'recoil'; +import { tripIdState, visitDateState } from '@recoil/socket'; import { useEffect } from 'react'; const SocketRoutes = () => { - const { id: tripId } = useParams(); - const [currentTripId, setCurrentTripId] = useRecoilState(tripIdState); + const tripId = useRecoilValue(tripIdState); + const visitDate = useRecoilValue(visitDateState); - useEffect(() => { - if (tripId) { - setCurrentTripId(tripId); - } - }, [tripId]); - - const visitDate = null; + if (!tripId || !visitDate) { + return
에러
; + } return ( - + } /> } /> From da682a634b6d24cc8659aab428e0729ab1951cb0 Mon Sep 17 00:00:00 2001 From: Hojin Date: Mon, 15 Jan 2024 16:48:12 +0900 Subject: [PATCH 12/16] =?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/Plan/PlanItem.tsx | 4 ++-- src/router/socketRouter.tsx | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/Plan/PlanItem.tsx b/src/components/Plan/PlanItem.tsx index 257a8e32..798060c0 100644 --- a/src/components/Plan/PlanItem.tsx +++ b/src/components/Plan/PlanItem.tsx @@ -1,12 +1,12 @@ import SubmitBtn from '@components/common/button/SubmitBtn'; -import { PlusIcon, CarIcon, BusIcon } from '@components/common/icons/Icons'; +import { PlusIcon } from '@components/common/icons/Icons'; import { useNavigate } from 'react-router-dom'; import PlanItemBox from './PlanItemBox'; import { useContext } from 'react'; import { socketContext } from '@hooks/useSocket'; import { pubEnterMember } from '@api/socket'; import { useEffect } from 'react'; -import { useRecoilValue, useRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { tripIdState, memberIdState } from '@recoil/socket'; const PlanItem = () => { diff --git a/src/router/socketRouter.tsx b/src/router/socketRouter.tsx index 4f39b3c5..0d3b67d9 100644 --- a/src/router/socketRouter.tsx +++ b/src/router/socketRouter.tsx @@ -5,10 +5,8 @@ import PlanPlaceTrip from '@pages/plan/planPlaceTrip.page'; import PlanPlaceSearch from '@pages/plan/planPlaceSearch.page'; import Trip from '@pages/trip/trip.page'; import MainLayout from './routerLayout'; -import { useParams } from 'react-router-dom'; -import { useRecoilValue, useRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { tripIdState, visitDateState } from '@recoil/socket'; -import { useEffect } from 'react'; const SocketRoutes = () => { const tripId = useRecoilValue(tripIdState); From 654acface5eb581d376291375507d02e6430d507 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Mon, 15 Jan 2024 16:54:01 +0900 Subject: [PATCH 13/16] =?UTF-8?q?Feat:=20=EC=9D=B4=EC=9A=A9=EC=95=BD?= =?UTF-8?q?=EA=B4=80=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/auth.types.ts | 1 + src/components/common/icons/Icons.tsx | 32 +++++++++++++++++++++++++++ src/pages/signup/signup.page.tsx | 29 ++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/@types/auth.types.ts b/src/@types/auth.types.ts index 03d9bf8e..b6e1ac93 100644 --- a/src/@types/auth.types.ts +++ b/src/@types/auth.types.ts @@ -13,6 +13,7 @@ export interface AuthRequest { export interface SignupFormValue extends AuthRequest { passwordCheck: string; + checkbox: boolean; } export interface EditPassword { diff --git a/src/components/common/icons/Icons.tsx b/src/components/common/icons/Icons.tsx index ca6db260..824a6dc5 100644 --- a/src/components/common/icons/Icons.tsx +++ b/src/components/common/icons/Icons.tsx @@ -1207,3 +1207,35 @@ export const BusIcon: React.FC = ({ ); }; + +export const CheckboxIcon: React.FC = ({ + size = 21, + color = 'white', + fill = '#D7D7D7', +}) => { + return ( + + + + + + + ); +}; diff --git a/src/pages/signup/signup.page.tsx b/src/pages/signup/signup.page.tsx index 289e5746..77c69186 100644 --- a/src/pages/signup/signup.page.tsx +++ b/src/pages/signup/signup.page.tsx @@ -8,6 +8,7 @@ import { } from '@components/Auth'; import { BackBox } from '@components/common'; import SubmitBtn from '@components/common/button/SubmitBtn'; +import { CheckboxIcon } from '@components/common/icons/Icons'; import { setItem } from '@utils/localStorageFun'; import { SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; @@ -84,6 +85,34 @@ const Signup = () => { />
+ + 완료
From 449b62174406a0c998773d88ce65690e319cb4c8 Mon Sep 17 00:00:00 2001 From: jisu Seo Date: Mon, 15 Jan 2024 17:35:28 +0900 Subject: [PATCH 14/16] =?UTF-8?q?Refactor:=20=EC=97=AC=ED=96=89=20?= =?UTF-8?q?=EC=B7=A8=ED=96=A5=20=EB=AA=A8=EB=91=90=20=EC=84=A0=ED=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Auth/AuthSurvey/AuthSurvey.tsx | 7 ++----- src/components/Auth/AuthSurvey/AuthSurveyOption.tsx | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/Auth/AuthSurvey/AuthSurvey.tsx b/src/components/Auth/AuthSurvey/AuthSurvey.tsx index 94811ff6..7486b522 100644 --- a/src/components/Auth/AuthSurvey/AuthSurvey.tsx +++ b/src/components/Auth/AuthSurvey/AuthSurvey.tsx @@ -16,9 +16,8 @@ const AuthSurvey = ({ path }: Props) => { const { register, handleSubmit, - watch, setValue, - formState: { isDirty }, + formState: { isDirty, isValid }, } = useForm(); const navigate = useNavigate(); const [userInfo, _] = useRecoilState(UserInfoState); @@ -72,9 +71,7 @@ const AuthSurvey = ({ path }: Props) => { ))}
- - 완료 - + 완료 ); }; diff --git a/src/components/Auth/AuthSurvey/AuthSurveyOption.tsx b/src/components/Auth/AuthSurvey/AuthSurveyOption.tsx index 774317ff..309a6d07 100644 --- a/src/components/Auth/AuthSurvey/AuthSurveyOption.tsx +++ b/src/components/Auth/AuthSurvey/AuthSurveyOption.tsx @@ -40,7 +40,9 @@ const AuthSurveyOption = ({ content, name, register }: Props) => { type="radio" id={content} className={`hidden peer/${content.replace(' ', '')}`} - {...register(name)} + {...register(name, { + required: true, + })} value={content} />