From 18ca00c19018e357efa372a4cee27c54024c837a Mon Sep 17 00:00:00 2001 From: evaain706 Date: Mon, 11 Aug 2025 13:58:02 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[#158]=20fix:=20=ED=86=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=88=84=EB=9D=BD=EB=90=9C=EA=B3=B3=20=EC=A0=81=EC=9A=A9/?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activities/[id]/components/Title.tsx | 3 ++- .../activities/[id]/hooks/useDeleteActivity.ts | 1 + .../myactivity/[id]/hooks/useEditActivityForm.ts | 13 ++++++++++--- .../myactivity/hooks/useCreateActivityForm.ts | 3 ++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/app/(with-header)/activities/[id]/components/Title.tsx b/src/app/(with-header)/activities/[id]/components/Title.tsx index c8bf18d..d53ad6e 100644 --- a/src/app/(with-header)/activities/[id]/components/Title.tsx +++ b/src/app/(with-header)/activities/[id]/components/Title.tsx @@ -11,6 +11,7 @@ import { useParams, useRouter } from 'next/navigation'; import { useQueryClient } from '@tanstack/react-query'; import { useDeleteActivity } from '../hooks/useDeleteActivity'; import Popup from '@/components/Popup'; +import { toast } from 'sonner'; interface TitleProps { title: string; @@ -45,8 +46,8 @@ function Title({ if (!id) return; mutate(id as string); setIsPopupOpen(false); + toast.success('체험이 삭제되었습니다!'); }; - return ( <> diff --git a/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts b/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts index 7d6dfff..5a12ff7 100644 --- a/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts +++ b/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts @@ -23,6 +23,7 @@ export const useDeleteActivity = () => { }); queryClient.invalidateQueries({ queryKey: ['popularExperiences'] }); router.push(`/`); + toast.success('체험을 삭제했습니다!'); }, onError: (error: AxiosError) => { const responseData = error.response?.data as diff --git a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts index 6290a04..efa4e58 100644 --- a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts +++ b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts @@ -209,9 +209,16 @@ export const useEditActivityForm = () => { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - const validationMessage = validateSchedules(dates); - if (validationMessage) { - toast.error(validationMessage); + if ( + !title || + !category || + !description || + !address || + !price || + !mainImage || + dates.length === 0 + ) { + toast.error('소개이미지를 제외한 모든값은 필수값입니다!'); return; } try { diff --git a/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts b/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts index e3ca6d5..1f5c3f1 100644 --- a/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts +++ b/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts @@ -132,9 +132,10 @@ export const useCreateActivityForm = () => { !description || !address || !price || + !mainImage || dates.length === 0 ) { - toast.error('모든 필드를 입력해주세요.'); + toast.error('소개이미지를 제외한 모든값은 필수값입니다!'); return; } mutation.mutate(); From 9d222c3924da7d021d46f326b9cc0e97860e8912 Mon Sep 17 00:00:00 2001 From: evaain706 Date: Tue, 12 Aug 2025 16:56:38 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[#158]=20refactor:=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20=ED=99=95=EB=8C=80?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20=EC=B6=94=EA=B0=80/=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20UI=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/img/default-bg.png | Bin 0 -> 854 bytes .../activities/[id]/components/ImageGrid.tsx | 71 ++++++++++++++---- src/components/DatePicker/CalendarBody.tsx | 2 +- src/components/FloatingBox/PriceDisplay.tsx | 17 ++++- 4 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 public/assets/img/default-bg.png diff --git a/public/assets/img/default-bg.png b/public/assets/img/default-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..58a4a779aeb6697af6cb57a5dd1fb43989027dd1 GIT binary patch literal 854 zcmeAS@N?(olHy`uVBq!ia0vp^4?&oN8Ax*GDtQ2@gaDrq*Z=?jr=_J$nlvdXDXG7| zKPxNi*RNm6$;mM>F;P)b@7}$Oi;D{n55Ic#>akMkD5*t|OHOogphoSwJ8Y@f__$t6{BrAyqx*fobDBN|&PFML0(`KNH@Hplz@hvvIK z^wr*cchL2GwER&o2(Y>nEIpK;P9Wlm5Fk#&ky`k*+22eEPk%r?b{fYG0*Ppn1i{4MVW$!xq=DTjY z^`{?k`{ki_=)zS@LMQ1-bIeW9#-U1Pet%37zwKw{H{rPq3JHB__hqzxK2z>bB z!isCJzqd|*<7E6!I{(TlJM~lP?|*md&AGAYac|Vz`VVLKc245&hK<~PFT2&{k>sfxTTc|iRlyUU@&W9Xc|*e&{oEr`9zJ9K*>s~Fp?#Oe$n*YvPj;G_6>HfnX24*6$azdL<;DcpZ?I_+|d~8!Ug1^c*>V23P6=ivL+tZ&{$^xODQx PSs+!Ou6{1-oD!M<68f8^ literal 0 HcmV?d00001 diff --git a/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx b/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx index e5cd38e..25b626d 100644 --- a/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx +++ b/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx @@ -4,21 +4,36 @@ import Image from 'next/image'; import React, { useState } from 'react'; import { ImageGridProps } from '@/types/activityDetailType'; import { AnimatePresence, motion } from 'framer-motion'; +import Modal from '@/components/Modal'; -function ImageGrid({ mainImage, subImages }: ImageGridProps) { - const images = [mainImage, ...subImages]; +const DEFAULT_IMAGE = '/assets/img/default-bg.png'; +function ImageGrid({ mainImage, subImages }: ImageGridProps) { + const [image, setImage] = useState([mainImage, ...subImages]); const [currentIndex, setCurrentIndex] = useState(0); const [direction, setDirection] = useState(0); + const [isOpen, setIsOpen] = useState(false); + const [selectedImage, setSelectedImage] = useState(null); + + const handleImageClick = (image: string) => { + setSelectedImage(image); + setIsOpen(true); + }; + + const handleImageError = (index: number) => { + setImage((prev) => + prev.map((src, i) => (i === index ? DEFAULT_IMAGE : src)), + ); + }; const prevSlide = () => { setDirection(-1); - setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1)); + setCurrentIndex((prev) => (prev === 0 ? image.length - 1 : prev - 1)); }; const nextSlide = () => { setDirection(1); - setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1)); + setCurrentIndex((prev) => (prev === image.length - 1 ? 0 : prev + 1)); }; const variants = { @@ -26,10 +41,7 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) { x: direction > 0 ? 300 : -300, opacity: 0, }), - center: { - x: 0, - opacity: 1, - }, + center: { x: 0, opacity: 1 }, exit: (direction: number) => ({ x: direction > 0 ? -300 : 300, opacity: 0, @@ -55,11 +67,13 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) { className='absolute inset-0' > {` handleImageError(currentIndex)} /> @@ -81,7 +95,7 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) {
- {images.map((_, i) => ( + {image.map((_, i) => (
-
+
handleImageClick(mainImage)} + className='relative col-span-2 row-span-4 hover:animate-pulse' + > 메인이미지 handleImageError(0)} />
- {subImages.slice(0, 4).map((image, index) => ( + {image.slice(1, 5).map((image, index) => (
handleImageClick(image)} className='relative col-span-1 row-span-2 h-full hover:animate-pulse' > {`서브이미지 handleImageError(index + 1)} />
))}
+ + + + + + +
+ {selectedImage && ( + 확대 이미지 + )} +
+
+ + +
+
); } diff --git a/src/components/DatePicker/CalendarBody.tsx b/src/components/DatePicker/CalendarBody.tsx index 195dcfd..a72d761 100644 --- a/src/components/DatePicker/CalendarBody.tsx +++ b/src/components/DatePicker/CalendarBody.tsx @@ -73,7 +73,7 @@ export default function CalendarBody({ !isToday && !isSelected && !isSameMonth ? 'hover:bg-gray-50' : '' - } ${isHighlighted && !isSelected ? 'bg-yellow-200' : ''} `} + } ${isHighlighted && !isSelected ? 'bg-yellow-300' : ''} ${!isHighlighted ? 'opacity-50' : ''}`} aria-label={`${day.format('YYYY년 MM월 DD일')} ${ isToday ? '오늘' : '' } ${isSelected ? '선택됨' : ''}`} diff --git a/src/components/FloatingBox/PriceDisplay.tsx b/src/components/FloatingBox/PriceDisplay.tsx index 4fd270d..c3e8953 100644 --- a/src/components/FloatingBox/PriceDisplay.tsx +++ b/src/components/FloatingBox/PriceDisplay.tsx @@ -1,9 +1,18 @@ export default function PriceDisplay({ price }: { price: number }) { return ( -
-
- ₩{price.toLocaleString('ko-KR')}{' '} - / 인 +
+
+

+ ₩{price.toLocaleString('ko-KR')} + /인 +

+ +
+
+ + : 예약 가능 일자 + +
); From 9c7f66ab4234905c369de760d15bc0df8df8ad18 Mon Sep 17 00:00:00 2001 From: evaain706 Date: Sun, 17 Aug 2025 02:41:24 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=82=AD=EC=A0=9C=20/=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activities/[id]/mock/mock.ts | 58 --------------- .../FloatingBox/BookingInterface.tsx | 65 ++-------------- src/components/FloatingBox/TabletPopup.tsx | 29 -------- src/components/Modal/Example/TestModal.tsx | 39 ---------- .../Modal/Example/TestModalButton.tsx | 23 ------ .../Modal/Example/UncontrolledModal.tsx | 18 ----- src/components/Modal/Example/readme | 38 ---------- src/hooks/useBooking.ts | 74 +++++++++++++++++++ 8 files changed, 81 insertions(+), 263 deletions(-) delete mode 100644 src/app/(with-header)/activities/[id]/mock/mock.ts delete mode 100644 src/components/FloatingBox/TabletPopup.tsx delete mode 100644 src/components/Modal/Example/TestModal.tsx delete mode 100644 src/components/Modal/Example/TestModalButton.tsx delete mode 100644 src/components/Modal/Example/UncontrolledModal.tsx delete mode 100644 src/components/Modal/Example/readme create mode 100644 src/hooks/useBooking.ts diff --git a/src/app/(with-header)/activities/[id]/mock/mock.ts b/src/app/(with-header)/activities/[id]/mock/mock.ts deleted file mode 100644 index fe2f95b..0000000 --- a/src/app/(with-header)/activities/[id]/mock/mock.ts +++ /dev/null @@ -1,58 +0,0 @@ -export const mockActivity = { - id: 5088, - userId: 2145, - title: '함께 배우면 즐거운 스트릿댄스', - description: '둠칫 둠칫 두둠칫', - category: '투어', - price: 10000, - address: '서울특별시 강남구 테헤란로 427', - bannerImageUrl: '/test/image1.png', - rating: 0, - reviewCount: 0, - createdAt: '2025-07-16T16:49:19.971Z', - updatedAt: '2025-07-16T16:49:19.971Z', - subImages: [ - { - id: 10643, - imageUrl: '/test/image2.png', - }, - { - id: 10644, - imageUrl: '/test/image3.png', - }, - { - id: 10645, - imageUrl: '/test/image4.png', - }, - { - id: 10646, - imageUrl: '/test/image5.png', - }, - ], - schedules: [ - { - id: 21515, - date: '2025-12-01', - startTime: '12:00', - endTime: '13:00', - }, - { - id: 21516, - date: '2025-12-05', - startTime: '12:00', - endTime: '13:00', - }, - { - id: 21517, - date: '2025-12-05', - startTime: '13:00', - endTime: '14:00', - }, - { - id: 21518, - date: '2025-12-05', - startTime: '14:00', - endTime: '15:00', - }, - ], -}; diff --git a/src/components/FloatingBox/BookingInterface.tsx b/src/components/FloatingBox/BookingInterface.tsx index 5158b1a..5304699 100644 --- a/src/components/FloatingBox/BookingInterface.tsx +++ b/src/components/FloatingBox/BookingInterface.tsx @@ -9,12 +9,7 @@ import TotalPriceDisplay from './TotalPriceDisplay'; import BookingModal from '@/ui/BookingModal'; import DatePicker from '../DatePicker/DatePicker'; import { SchedulesProps } from '@/types/activityDetailType'; -import { privateInstance } from '@/apis/privateInstance'; -import { useParams } from 'next/navigation'; -import { AxiosError } from 'axios'; -import useUserStore from '@/stores/authStore'; -import { toast } from 'sonner'; -import { useState } from 'react'; +import { useBooking } from '@/hooks/useBooking'; export default function BookingInterface({ schedules, @@ -27,62 +22,16 @@ export default function BookingInterface({ isOwner: boolean; price: number; }) { - const [onBooking, setOnBooking] = useState(false); - const { user } = useUserStore(); const setIsOpen = useBookingStore((state) => state.setIsOpen); + const { + onBooking, + handleBooking, + isBookable, + buttonText, selectedDate, selectedTime, - participants, - selectedTimeId, - setToInitial, - } = useBookingStore(); - - const { id } = useParams(); - - const handleBooking = async () => { - setOnBooking(true); - try { - await privateInstance.post(`/activities/${id}/reservation`, { - selectedTimeId, - participants, - }); - - toast.success('예약되었습니다!'); - setToInitial(); - } catch (err) { - const error = err as AxiosError; - const responseData = error.response?.data as - | { error?: string; message?: string } - | undefined; - - console.error('전체 에러:', error); - - toast.error( - responseData?.error || - responseData?.message || - error.message || - '예약에 실패했습니다.', - ); - } finally { - setOnBooking(false); - } - }; - - const isLoggedIn = !!user; - const isBookable = - !!selectedDate && - !!selectedTime && - !!selectedTimeId && - !!participants && - !isOwner && - isLoggedIn; - - const buttonText = !isLoggedIn - ? '로그인이 필요한 기능입니다' - : isOwner - ? '본인이 등록한 체험입니다' - : '예약하기'; + } = useBooking(isOwner); return (
diff --git a/src/components/FloatingBox/TabletPopup.tsx b/src/components/FloatingBox/TabletPopup.tsx deleted file mode 100644 index e3f01a3..0000000 --- a/src/components/FloatingBox/TabletPopup.tsx +++ /dev/null @@ -1,29 +0,0 @@ -// 'use client'; - -// import useBookingStore from '@/stores/Booking/useBookingStore'; -// import IconClose from '@assets/svg/close'; -// import DatePicker from '../DatePicker/DatePicker'; -// import TimeSelector from './TimeSelector'; -// import { SchedulesProps } from '@/types/activityDetailType'; - -// export default function TabletPopup({schedules}:SchedulesProps) { -// const isOpen = useBookingStore((state) => state.isOpen); -// const setIsOpen = useBookingStore((state) => state.setIsOpen); - -// if (!isOpen) return null; - -// return ( -//
-//
-//

날짜

-// -//
- -// - -// -//
-// ); -// } diff --git a/src/components/Modal/Example/TestModal.tsx b/src/components/Modal/Example/TestModal.tsx deleted file mode 100644 index a630f87..0000000 --- a/src/components/Modal/Example/TestModal.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client'; - -import Modal from '@/components/Modal'; - -export default function TestModal({ - isOpen, - setIsOpen, -}: { - isOpen: boolean; - setIsOpen: React.Dispatch>; -}) { - //예시 동작 - function TestAction() { - window.alert('리뷰 작성'); - setIsOpen(false); - } - - return ( - // 외부에서 정의된 모달 제어 state를 받아서 사용 - - - - 제목 - - - 제어모달예시 - - - - - - - ); -} diff --git a/src/components/Modal/Example/TestModalButton.tsx b/src/components/Modal/Example/TestModalButton.tsx deleted file mode 100644 index b9af075..0000000 --- a/src/components/Modal/Example/TestModalButton.tsx +++ /dev/null @@ -1,23 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import TestModal from './TestModal'; - -export default function TestModalButton() { - const [isOpen, setIsOpen] = useState(false); //외부에서 모달을 제어하기위한 state 정의 - - return ( -
- - - {/* props로 state를 내려줌 */} - -
- ); -} diff --git a/src/components/Modal/Example/UncontrolledModal.tsx b/src/components/Modal/Example/UncontrolledModal.tsx deleted file mode 100644 index ffc909c..0000000 --- a/src/components/Modal/Example/UncontrolledModal.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import Modal from '..'; - -export default function UncontrolledModal() { - return ( - - 비제어 모달 열기 - - - 제목 - - - 비제어모달 - - - - - ); -} diff --git a/src/components/Modal/Example/readme b/src/components/Modal/Example/readme deleted file mode 100644 index 4331d42..0000000 --- a/src/components/Modal/Example/readme +++ /dev/null @@ -1,38 +0,0 @@ -모달 제어/비제어 사용 예시를 보여드리기위해 만들어둔 폴더입니다. - -제어모달예시 - TestModalButton.tsx , TestModal.tsx - -비제어모달예시 - UncontrolledModal.tsx - - ---- - -# 제어(Controlled) 모달 - -- 외부에서 모달의 열림/닫힘 상태를 직접 관리하는 방식입니다. -- 보통 `useState`로 상태를 만들고, `isOpen`, `onOpenChange`(또는 setState)를 모달에 전달합니다. -- 모달을 열거나 닫는 로직을 컴포넌트 외부에서 제어할 수 있어, 복잡한 조건이나 여러 곳에서 모달 상태를 변경해야 할 때 유용합니다. - -**예시 파일:** -- `TestModalButton.tsx` -- `TestModal.tsx` - - ---- - -# 비제어(Uncontrolled) 모달 - -- **모달 컴포넌트 내부에서 열림/닫힘 상태를 자체적으로 관리**하는 방식입니다. -- 별도의 상태 관리가 필요 없고, 간단하게 모달을 띄우고 닫을 때 사용하기 좋습니다. -- 외부에서 모달의 상태를 직접 제어할 수 없으므로, 단순한 용도에 적합합니다. - -**예시 파일:** -- `UncontrolledModal.tsx` - ---- - -## 요약 - -- **제어 모달**: 외부에서 상태를 관리하며, 복잡한 상황에 적합(어떤 상황발생시 트리거 되어 열리고 특정 액션(폼 작성후 제출등)이 트리거되어 닫혀야하는모달) -- **비제어 모달**: 내부에서 상태를 관리하며, 간단한 상황에 적합(엮인 동작이 없는 단순 정보출력용 모달) - diff --git a/src/hooks/useBooking.ts b/src/hooks/useBooking.ts new file mode 100644 index 0000000..d2abbad --- /dev/null +++ b/src/hooks/useBooking.ts @@ -0,0 +1,74 @@ +'use client'; + +import { useParams } from 'next/navigation'; +import { privateInstance } from '@/apis/privateInstance'; +import { AxiosError } from 'axios'; +import { toast } from 'sonner'; +import useBookingStore from '@/stores/Booking/useBookingStore'; +import useUserStore from '@/stores/authStore'; +import { useMutation } from '@tanstack/react-query'; + +export const useBooking = (isOwner: boolean) => { + const { id } = useParams(); + const { user } = useUserStore(); + + const { + selectedDate, + selectedTime, + participants, + selectedTimeId, + setToInitial, + } = useBookingStore(); + + const bookingMutation = useMutation({ + mutationFn: async () => { + return await privateInstance.post(`/activities/${id}/reservation`, { + selectedTimeId, + participants, + }); + }, + onSuccess: () => { + toast.success('예약되었습니다!'); + setToInitial(); + }, + onError: (err) => { + const error = err as AxiosError; + const responseData = error.response?.data as + | { error?: string; message?: string } + | undefined; + + console.error('전체 에러:', error); + + toast.error( + responseData?.error || + responseData?.message || + error.message || + '예약에 실패했습니다.', + ); + }, + }); + + const isLoggedIn = !!user; + const isBookable = + !!selectedDate && + !!selectedTime && + !!selectedTimeId && + !!participants && + !isOwner && + isLoggedIn; + + const buttonText = !isLoggedIn + ? '로그인이 필요한 기능입니다' + : isOwner + ? '본인이 등록한 체험입니다' + : '예약하기'; + + return { + onBooking: bookingMutation.isPending, + handleBooking: () => bookingMutation.mutate(), + isBookable, + buttonText, + selectedDate, + selectedTime, + }; +}; From 2b0e3c35c0ef70dc2907af0788d4eefeb9744ffb Mon Sep 17 00:00:00 2001 From: evaain706 Date: Sun, 17 Aug 2025 03:01:19 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[#158]=20refactor:=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EB=A1=9C=EC=A7=81=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 --- .../activities/[id]/components/ImageGrid.tsx | 7 +- .../[id]/components/ReviewSection.tsx | 19 +-- .../[id]/components/ReviewTitle.tsx | 5 +- .../activities/[id]/components/Title.tsx | 10 +- .../[id]/components/EditActivityForm.tsx | 6 +- .../[id]/hooks/useEditActivityForm.ts | 7 +- .../myactivity/components/AddressInput.tsx | 16 +-- .../myactivity/components/CategoryInput.tsx | 34 ++++-- .../myactivity/components/FormSection.tsx | 7 +- .../myactivity/components/ImagePreview.tsx | 18 ++- .../myactivity/components/ImageSection.tsx | 12 +- .../myactivity/components/ImageUpload.tsx | 8 +- .../myactivity/components/InfoSection.tsx | 14 +-- .../myactivity/components/MainImageSelect.tsx | 7 +- .../myactivity/components/ScheduleSelect.tsx | 14 +-- .../components/ScheduleSelectForm.tsx | 26 +--- .../myactivity/components/SubImageSelect.tsx | 7 +- .../myactivity/hooks/useCreateActivityForm.ts | 7 +- .../myactivity/utils/dateValidatoin.ts | 11 ++ src/components/FloatingBox/BookingButton.tsx | 9 +- src/constants/AvatarConstants.ts | 3 + src/types/activityDetailType.ts | 33 ++++++ src/types/addEditExperienceType.ts | 111 ++++++++++++++++++ src/types/bookingInterfaceType.ts | 7 ++ 24 files changed, 217 insertions(+), 181 deletions(-) create mode 100644 src/types/addEditExperienceType.ts create mode 100644 src/types/bookingInterfaceType.ts diff --git a/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx b/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx index 25b626d..a993a3d 100644 --- a/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx +++ b/src/app/(with-header)/activities/[id]/components/ImageGrid.tsx @@ -5,8 +5,7 @@ import React, { useState } from 'react'; import { ImageGridProps } from '@/types/activityDetailType'; import { AnimatePresence, motion } from 'framer-motion'; import Modal from '@/components/Modal'; - -const DEFAULT_IMAGE = '/assets/img/default-bg.png'; +import { DEFAULT_BG } from '@/constants/AvatarConstants'; function ImageGrid({ mainImage, subImages }: ImageGridProps) { const [image, setImage] = useState([mainImage, ...subImages]); @@ -21,9 +20,7 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) { }; const handleImageError = (index: number) => { - setImage((prev) => - prev.map((src, i) => (i === index ? DEFAULT_IMAGE : src)), - ); + setImage((prev) => prev.map((src, i) => (i === index ? DEFAULT_BG : src))); }; const prevSlide = () => { diff --git a/src/app/(with-header)/activities/[id]/components/ReviewSection.tsx b/src/app/(with-header)/activities/[id]/components/ReviewSection.tsx index 51a889c..c2d45cc 100644 --- a/src/app/(with-header)/activities/[id]/components/ReviewSection.tsx +++ b/src/app/(with-header)/activities/[id]/components/ReviewSection.tsx @@ -9,24 +9,9 @@ import { privateInstance } from '@/apis/privateInstance'; import ReviewTitle from './ReviewTitle'; import useUserStore from '@/stores/authStore'; import cn from '@/lib/cn'; - import ReviewCardSkeleton from './Skeletons/ReviewCardSkeleton'; - -interface ReviewSectionProps { - activityId: string; - reviewCount: number; - rating: number; -} - -interface ReviewProps { - id: string; - user: { - nickname: string; - profileImageUrl: string; - }; - createdAt: string; - content: string; -} +import { ReviewSectionProps } from '@/types/activityDetailType'; +import { ReviewProps } from '@/types/activityDetailType'; function ReviewSection({ activityId, diff --git a/src/app/(with-header)/activities/[id]/components/ReviewTitle.tsx b/src/app/(with-header)/activities/[id]/components/ReviewTitle.tsx index 3f37863..7dadf06 100644 --- a/src/app/(with-header)/activities/[id]/components/ReviewTitle.tsx +++ b/src/app/(with-header)/activities/[id]/components/ReviewTitle.tsx @@ -2,11 +2,8 @@ import Star from '@assets/svg/star'; import { useState, useEffect } from 'react'; +import { ReviewTitleProps } from '@/types/activityDetailType'; -interface ReviewTitleProps { - reviewCount: number; - rating: number; -} export default function ReviewTitle({ reviewCount = 0, rating = 0, diff --git a/src/app/(with-header)/activities/[id]/components/Title.tsx b/src/app/(with-header)/activities/[id]/components/Title.tsx index d53ad6e..f7dbabc 100644 --- a/src/app/(with-header)/activities/[id]/components/Title.tsx +++ b/src/app/(with-header)/activities/[id]/components/Title.tsx @@ -12,15 +12,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { useDeleteActivity } from '../hooks/useDeleteActivity'; import Popup from '@/components/Popup'; import { toast } from 'sonner'; - -interface TitleProps { - title: string; - category: string; - rating: number; - reviewCount: number; - address: string; - isOwner: boolean; -} +import { TitleProps } from '@/types/activityDetailType'; function Title({ title, diff --git a/src/app/(with-header)/myactivity/[id]/components/EditActivityForm.tsx b/src/app/(with-header)/myactivity/[id]/components/EditActivityForm.tsx index 7559535..90328d5 100644 --- a/src/app/(with-header)/myactivity/[id]/components/EditActivityForm.tsx +++ b/src/app/(with-header)/myactivity/[id]/components/EditActivityForm.tsx @@ -6,11 +6,7 @@ import { ScheduleSelectForm } from '../../components/ScheduleSelectForm'; import { ImageSection } from '../../components/ImageSection'; import { useEditActivityForm } from '../hooks/useEditActivityForm'; import EditActivityFormSkeleton from '../../loading'; - -interface SubImageType { - id?: number; - url: string | File; -} +import { SubImageType } from '@/types/addEditExperienceType'; export default function EditActivityForm() { const { diff --git a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts index efa4e58..8225fd9 100644 --- a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts +++ b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts @@ -9,12 +9,7 @@ import { ActivityDetailEdit, Schedule } from '@/types/activityDetailType'; import { AxiosError } from 'axios'; import { toast } from 'sonner'; import { notFound } from 'next/navigation'; -import { validateSchedules } from '../../utils/dateValidatoin'; - -interface SubImageType { - id?: number; - url: string | File; -} +import { SubImageType } from '@/types/addEditExperienceType'; export const useEditActivityForm = () => { const { id } = useParams() as { id: string }; diff --git a/src/app/(with-header)/myactivity/components/AddressInput.tsx b/src/app/(with-header)/myactivity/components/AddressInput.tsx index 86a52d9..49321eb 100644 --- a/src/app/(with-header)/myactivity/components/AddressInput.tsx +++ b/src/app/(with-header)/myactivity/components/AddressInput.tsx @@ -5,20 +5,8 @@ import DaumPostcode from 'react-daum-postcode'; import { useState } from 'react'; import Input from '@/components/Input'; import Button from '@/components/Button'; - -interface AddressInputProps { - onAddressChange: (address: string) => void; - address: string; -} - -interface PostcodeData { - address: string; - addressType: 'R' | 'J'; - bname: string; - buildingName: string; - zonecode: string; - userSelectedType: string; -} +import { AddressInputProps } from '@/types/addEditExperienceType'; +import { PostcodeData } from '@/types/addEditExperienceType'; export default function AddressInput({ onAddressChange, diff --git a/src/app/(with-header)/myactivity/components/CategoryInput.tsx b/src/app/(with-header)/myactivity/components/CategoryInput.tsx index 2fecdac..e9c059f 100644 --- a/src/app/(with-header)/myactivity/components/CategoryInput.tsx +++ b/src/app/(with-header)/myactivity/components/CategoryInput.tsx @@ -1,9 +1,5 @@ import ChevronIcon from '@assets/svg/chevron'; // 아이콘 경로는 맞게 조정 - -interface CategoryProps { - category?: string; - onCategoryChange: (value: string) => void; -} +import { CategoryProps } from '@/types/addEditExperienceType'; export default function CategoryInput({ category, @@ -16,7 +12,7 @@ export default function CategoryInput({ */}
{/* 커스텀 화살표 아이콘 */} -
+
diff --git a/src/app/(with-header)/myactivity/components/FormSection.tsx b/src/app/(with-header)/myactivity/components/FormSection.tsx index cb33e7c..f3534de 100644 --- a/src/app/(with-header)/myactivity/components/FormSection.tsx +++ b/src/app/(with-header)/myactivity/components/FormSection.tsx @@ -1,10 +1,5 @@ import type React from 'react'; - -interface FormSectionProps { - title: string; - children: React.ReactNode; - description?: string; -} +import { FormSectionProps } from '@/types/addEditExperienceType'; export function FormSection({ title, diff --git a/src/app/(with-header)/myactivity/components/ImagePreview.tsx b/src/app/(with-header)/myactivity/components/ImagePreview.tsx index 1948f6e..31a0de6 100644 --- a/src/app/(with-header)/myactivity/components/ImagePreview.tsx +++ b/src/app/(with-header)/myactivity/components/ImagePreview.tsx @@ -1,14 +1,8 @@ 'use client'; import IconClose from '@assets/svg/close'; -import { useState,useEffect } from 'react'; - -interface ImagePreviewProps { - image: File | string; - onRemove: () => void; - alt: string; - className?: string; -} +import { useState, useEffect } from 'react'; +import { ImagePreviewProps } from '@/types/addEditExperienceType'; export function ImagePreview({ image, @@ -43,10 +37,14 @@ export function ImagePreview({
); diff --git a/src/app/(with-header)/myactivity/components/ImageSection.tsx b/src/app/(with-header)/myactivity/components/ImageSection.tsx index eddd9b3..24390ca 100644 --- a/src/app/(with-header)/myactivity/components/ImageSection.tsx +++ b/src/app/(with-header)/myactivity/components/ImageSection.tsx @@ -2,22 +2,14 @@ import { MainImageSelect } from './MainImageSelect'; import { SubImageSelect } from './SubImageSelect'; - -interface ImagesSectionProps { - mainImage: string | File | null; - subImage: (string | File)[]; - onMainImageSelect: (file: File) => void; - onMainImageRemove: () => void; - onSubImageAdd: (files: File[]) => void; - onSubImageRemove: (index: number) => void; -} +import { ImagesSectionProps } from '@/types/addEditExperienceType'; export function ImageSection({ mainImage, subImage, onMainImageSelect, onMainImageRemove, - onSubImageAdd, + onSubImageAdd, onSubImageRemove, }: ImagesSectionProps) { return ( diff --git a/src/app/(with-header)/myactivity/components/ImageUpload.tsx b/src/app/(with-header)/myactivity/components/ImageUpload.tsx index 12a9bb9..68465be 100644 --- a/src/app/(with-header)/myactivity/components/ImageUpload.tsx +++ b/src/app/(with-header)/myactivity/components/ImageUpload.tsx @@ -1,13 +1,7 @@ 'use client'; import type React from 'react'; - -interface ImageUploadProps { - onImageSelect: (file: File) => void; - multiple?: boolean; - className?: string; - children?: React.ReactNode; -} +import { ImageUploadProps } from '@/types/addEditExperienceType'; export function ImageUpload({ onImageSelect, diff --git a/src/app/(with-header)/myactivity/components/InfoSection.tsx b/src/app/(with-header)/myactivity/components/InfoSection.tsx index c507ac6..7f1631b 100644 --- a/src/app/(with-header)/myactivity/components/InfoSection.tsx +++ b/src/app/(with-header)/myactivity/components/InfoSection.tsx @@ -4,19 +4,7 @@ import Input from '@/components/Input'; import AddressInput from './AddressInput'; import CategoryInput from './CategoryInput'; import Textarea from '@/components/Textarea'; - -interface InfoSectionProps { - title?: string; - category?: string; - price?: string; - description?: string; - address?: string; - onTitleChange: (value: string) => void; - onCategoryChange: (value: string) => void; - onPriceChange: (value: string) => void; - onDescriptionChange: (value: string) => void; - onAddressChange: (value: string) => void; -} +import { InfoSectionProps } from '@/types/addEditExperienceType'; export function InfoSection({ title = '', diff --git a/src/app/(with-header)/myactivity/components/MainImageSelect.tsx b/src/app/(with-header)/myactivity/components/MainImageSelect.tsx index 354cd84..22c461d 100644 --- a/src/app/(with-header)/myactivity/components/MainImageSelect.tsx +++ b/src/app/(with-header)/myactivity/components/MainImageSelect.tsx @@ -2,12 +2,7 @@ import { ImageUpload } from './ImageUpload'; import { ImagePreview } from './ImagePreview'; - -interface MainImageSelectProps { - mainImage: File | string | null; - onImageSelect: (file: File) => void; - onImageRemove: () => void; -} +import { MainImageSelectProps } from '@/types/addEditExperienceType'; export function MainImageSelect({ mainImage, diff --git a/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx b/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx index c64fd3f..50ee853 100644 --- a/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx +++ b/src/app/(with-header)/myactivity/components/ScheduleSelect.tsx @@ -2,19 +2,7 @@ import Input from '@/components/Input'; import IconClose from '@assets/svg/close'; - -interface ScheduleSelectProps { - index: number; - isRemovable: boolean; - onAddDate: () => void; - onRemove: (index: number) => void; - onDateChange: (index: number, value: string) => void; - onStartTimeChange: (index: number, value: string) => void; - onEndTimeChange: (index: number, value: string) => void; - date: string; - startTime: string; - endTime: string; -} +import { ScheduleSelectProps } from '@/types/addEditExperienceType'; export function ScheduleSelect({ index, diff --git a/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx b/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx index 4e63ec1..0a0361a 100644 --- a/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx +++ b/src/app/(with-header)/myactivity/components/ScheduleSelectForm.tsx @@ -2,29 +2,9 @@ import { toast } from 'sonner'; import { ScheduleSelect } from './ScheduleSelect'; -import { Schedule } from '@/types/activityDetailType'; - -interface ScheduleSelectFormProps { - dates: Schedule[]; - onAddDate: () => void; - onRemoveDate: (index: number) => void; - onDateChange: ( - index: number, - field: keyof Omit, - value: string, - ) => void; -} - -function isPastDate(dateStr: string) { - const selected = new Date(dateStr); - const today = new Date(); - today.setHours(0, 0, 0, 0); - return selected < today; -} - -function isInvalidTimeRange(start: string, end: string) { - return start >= end; -} +import { ScheduleSelectFormProps } from '@/types/addEditExperienceType'; +import { isPastDate } from '../utils/dateValidatoin'; +import { isInvalidTimeRange } from '../utils/dateValidatoin'; export function ScheduleSelectForm({ dates, diff --git a/src/app/(with-header)/myactivity/components/SubImageSelect.tsx b/src/app/(with-header)/myactivity/components/SubImageSelect.tsx index ff8ae54..1e0a30c 100644 --- a/src/app/(with-header)/myactivity/components/SubImageSelect.tsx +++ b/src/app/(with-header)/myactivity/components/SubImageSelect.tsx @@ -1,11 +1,6 @@ import { ImagePreview } from './ImagePreview'; import { ImageUpload } from './ImageUpload'; - -interface SubImageSelectProps { - subImage: (string | File)[]; - onImagesAdd: (files: File[]) => void; - onImageRemove: (index: number) => void; -} +import { SubImageSelectProps } from '@/types/addEditExperienceType'; export function SubImageSelect({ subImage, diff --git a/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts b/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts index 1f5c3f1..e21806d 100644 --- a/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts +++ b/src/app/(with-header)/myactivity/hooks/useCreateActivityForm.ts @@ -8,12 +8,7 @@ import axios from 'axios'; import { uploadImage } from '../utils/uploadImage'; import { privateInstance } from '@/apis/privateInstance'; import { useQueryClient } from '@tanstack/react-query'; - -export interface DateSlot { - date: string; - startTime: string; - endTime: string; -} +import { DateSlot } from '@/types/addEditExperienceType'; export const useCreateActivityForm = () => { const [dates, setDates] = useState([ diff --git a/src/app/(with-header)/myactivity/utils/dateValidatoin.ts b/src/app/(with-header)/myactivity/utils/dateValidatoin.ts index 6aa91ce..c5a2283 100644 --- a/src/app/(with-header)/myactivity/utils/dateValidatoin.ts +++ b/src/app/(with-header)/myactivity/utils/dateValidatoin.ts @@ -29,3 +29,14 @@ export function validateSchedules(schedules: Schedule[]) { return null; } + +export function isPastDate(dateStr: string) { + const selected = new Date(dateStr); + const today = new Date(); + today.setHours(0, 0, 0, 0); + return selected < today; +} + +export function isInvalidTimeRange(start: string, end: string) { + return start >= end; +} diff --git a/src/components/FloatingBox/BookingButton.tsx b/src/components/FloatingBox/BookingButton.tsx index 3ae771e..93e6628 100644 --- a/src/components/FloatingBox/BookingButton.tsx +++ b/src/components/FloatingBox/BookingButton.tsx @@ -1,13 +1,6 @@ import React from 'react'; import { cn } from '@/lib/utils'; - -interface BookingButtonProps { - onClick: () => void; - children: React.ReactNode; - disabled?: boolean; - onBooking?: boolean; - className?: string; -} +import { BookingButtonProps } from '@/types/bookingInterfaceType'; export default function BookingButton({ onClick, diff --git a/src/constants/AvatarConstants.ts b/src/constants/AvatarConstants.ts index 0e5eeb8..b47adef 100644 --- a/src/constants/AvatarConstants.ts +++ b/src/constants/AvatarConstants.ts @@ -5,3 +5,6 @@ export const AVATAR_SIZE = { }; export const DEFAULT_IMG = '/assets/svg/profile-default.svg'; + + +export const DEFAULT_BG = '/assets/img/default-bg.png'; diff --git a/src/types/activityDetailType.ts b/src/types/activityDetailType.ts index 0f25401..b9f78c9 100644 --- a/src/types/activityDetailType.ts +++ b/src/types/activityDetailType.ts @@ -86,3 +86,36 @@ export interface ActivityDetailEdit { }[]; schedules: Schedule[]; } + + + +export interface TitleProps { + title: string; + category: string; + rating: number; + reviewCount: number; + address: string; + isOwner: boolean; +} + +export interface ReviewTitleProps { + reviewCount: number; + rating: number; +} + + +export interface ReviewSectionProps { + activityId: string; + reviewCount: number; + rating: number; +} + +export interface ReviewProps { + id: string; + user: { + nickname: string; + profileImageUrl: string; + }; + createdAt: string; + content: string; +} diff --git a/src/types/addEditExperienceType.ts b/src/types/addEditExperienceType.ts new file mode 100644 index 0000000..ae53d76 --- /dev/null +++ b/src/types/addEditExperienceType.ts @@ -0,0 +1,111 @@ +import { Schedule } from '@/types/activityDetailType'; + +export interface SubImageType { + id?: number; + url: string | File; +} + +export interface AddressInputProps { + onAddressChange: (address: string) => void; + address: string; +} + +export interface PostcodeData { + address: string; + addressType: 'R' | 'J'; + bname: string; + buildingName: string; + zonecode: string; + userSelectedType: string; +} + +export interface CategoryProps { + category?: string; + onCategoryChange: (value: string) => void; +} + +export interface FormSectionProps { + title: string; + children: React.ReactNode; + description?: string; +} + +export interface ImagePreviewProps { + image: File | string; + onRemove: () => void; + alt: string; + className?: string; +} + +export interface ImagesSectionProps { + mainImage: string | File | null; + subImage: (string | File)[]; + onMainImageSelect: (file: File) => void; + onMainImageRemove: () => void; + onSubImageAdd: (files: File[]) => void; + onSubImageRemove: (index: number) => void; +} + +export interface ImageUploadProps { + onImageSelect: (file: File) => void; + multiple?: boolean; + className?: string; + children?: React.ReactNode; +} + +export interface InfoSectionProps { + title?: string; + category?: string; + price?: string; + description?: string; + address?: string; + onTitleChange: (value: string) => void; + onCategoryChange: (value: string) => void; + onPriceChange: (value: string) => void; + onDescriptionChange: (value: string) => void; + onAddressChange: (value: string) => void; +} + +export interface MainImageSelectProps { + mainImage: File | string | null; + onImageSelect: (file: File) => void; + onImageRemove: () => void; +} + + +export interface SubImageSelectProps { + subImage: (string | File)[]; + onImagesAdd: (files: File[]) => void; + onImageRemove: (index: number) => void; +} + +export interface ScheduleSelectProps { + index: number; + isRemovable: boolean; + onAddDate: () => void; + onRemove: (index: number) => void; + onDateChange: (index: number, value: string) => void; + onStartTimeChange: (index: number, value: string) => void; + onEndTimeChange: (index: number, value: string) => void; + date: string; + startTime: string; + endTime: string; +} + +export interface ScheduleSelectFormProps { + dates: Schedule[]; + onAddDate: () => void; + onRemoveDate: (index: number) => void; + onDateChange: ( + index: number, + field: keyof Omit, + value: string, + ) => void; +} + + +export interface DateSlot { + date: string; + startTime: string; + endTime: string; +} diff --git a/src/types/bookingInterfaceType.ts b/src/types/bookingInterfaceType.ts new file mode 100644 index 0000000..6720b0e --- /dev/null +++ b/src/types/bookingInterfaceType.ts @@ -0,0 +1,7 @@ +export interface BookingButtonProps { + onClick: () => void; + children: React.ReactNode; + disabled?: boolean; + onBooking?: boolean; + className?: string; +} From c5a24569543e8116f82812c843e91e5512ff30aa Mon Sep 17 00:00:00 2001 From: evaain706 Date: Thu, 21 Aug 2025 07:48:46 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[#158]=20refactor:=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EB=8B=A8=EC=96=B8=20=EC=A0=9C=EA=B1=B0/config=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.ts | 4 ++++ .../activities/[id]/components/ActivityDetailForm.tsx | 2 +- src/app/(with-header)/activities/[id]/components/Title.tsx | 2 +- .../(with-header)/activities/[id]/hooks/useDeleteActivity.ts | 4 ++-- .../myactivity/[id]/hooks/useEditActivityForm.ts | 2 +- src/types/activityDetailType.ts | 5 +---- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/next.config.ts b/next.config.ts index ced4173..7ad5ff2 100644 --- a/next.config.ts +++ b/next.config.ts @@ -17,6 +17,10 @@ const nextConfig: NextConfig = { }, ], }, + + compiler: { + removeConsole: process.env.NODE_ENV === 'production', + }, }; export default nextConfig; diff --git a/src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx b/src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx index d078857..3b5cd6c 100644 --- a/src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx +++ b/src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx @@ -138,7 +138,7 @@ export default function ActivityDetailForm() { diff --git a/src/app/(with-header)/activities/[id]/components/Title.tsx b/src/app/(with-header)/activities/[id]/components/Title.tsx index f7dbabc..901a7fe 100644 --- a/src/app/(with-header)/activities/[id]/components/Title.tsx +++ b/src/app/(with-header)/activities/[id]/components/Title.tsx @@ -36,7 +36,7 @@ function Title({ const handleDeleteConfirm = () => { if (!id) return; - mutate(id as string); + mutate(Number(id)); setIsPopupOpen(false); toast.success('체험이 삭제되었습니다!'); }; diff --git a/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts b/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts index 5a12ff7..14470f2 100644 --- a/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts +++ b/src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts @@ -4,7 +4,7 @@ import { AxiosError } from 'axios'; import { useRouter } from 'next/navigation'; import { toast } from 'sonner'; -const deleteActivity = async (id: string) => { +const deleteActivity = async (id: number) => { const response = await privateInstance.delete(`/deleteActivity/${id}`); return response.data; }; @@ -23,7 +23,7 @@ export const useDeleteActivity = () => { }); queryClient.invalidateQueries({ queryKey: ['popularExperiences'] }); router.push(`/`); - toast.success('체험을 삭제했습니다!'); + toast.success('체험이 삭제되었습니다!'); }, onError: (error: AxiosError) => { const responseData = error.response?.data as diff --git a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts index 8225fd9..9a79d61 100644 --- a/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts +++ b/src/app/(with-header)/myactivity/[id]/hooks/useEditActivityForm.ts @@ -12,7 +12,7 @@ import { notFound } from 'next/navigation'; import { SubImageType } from '@/types/addEditExperienceType'; export const useEditActivityForm = () => { - const { id } = useParams() as { id: string }; + const { id } = useParams(); const router = useRouter(); const queryClient = useQueryClient(); diff --git a/src/types/activityDetailType.ts b/src/types/activityDetailType.ts index b9f78c9..8fbe42f 100644 --- a/src/types/activityDetailType.ts +++ b/src/types/activityDetailType.ts @@ -87,8 +87,6 @@ export interface ActivityDetailEdit { schedules: Schedule[]; } - - export interface TitleProps { title: string; category: string; @@ -103,9 +101,8 @@ export interface ReviewTitleProps { rating: number; } - export interface ReviewSectionProps { - activityId: string; + activityId: number; reviewCount: number; rating: number; } From 14d8e19c30dcff98777f7bd5830f2f01fe9c2f6a Mon Sep 17 00:00:00 2001 From: evaain706 Date: Thu, 21 Aug 2025 07:50:22 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[#158]=20fix:=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=ED=86=A0=EC=8A=A4=ED=8A=B8=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(with-header)/activities/[id]/components/Title.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/(with-header)/activities/[id]/components/Title.tsx b/src/app/(with-header)/activities/[id]/components/Title.tsx index 901a7fe..c0f42d8 100644 --- a/src/app/(with-header)/activities/[id]/components/Title.tsx +++ b/src/app/(with-header)/activities/[id]/components/Title.tsx @@ -38,7 +38,6 @@ function Title({ if (!id) return; mutate(Number(id)); setIsPopupOpen(false); - toast.success('체험이 삭제되었습니다!'); }; return ( From 93acc7008969bfc102813662cb998110d261ed86 Mon Sep 17 00:00:00 2001 From: evaain706 Date: Thu, 21 Aug 2025 08:05:12 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[#158}=20refactor:=20=EC=98=88=EC=95=BD?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=BA=98?= =?UTF-8?q?=EB=A6=B0=EB=8D=94=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activities/[id]/components/Title.tsx | 1 - src/components/DatePicker/CalendarBody.tsx | 56 +++++++++++-------- src/components/FloatingBox/PriceDisplay.tsx | 2 +- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/app/(with-header)/activities/[id]/components/Title.tsx b/src/app/(with-header)/activities/[id]/components/Title.tsx index c0f42d8..4f61807 100644 --- a/src/app/(with-header)/activities/[id]/components/Title.tsx +++ b/src/app/(with-header)/activities/[id]/components/Title.tsx @@ -11,7 +11,6 @@ import { useParams, useRouter } from 'next/navigation'; import { useQueryClient } from '@tanstack/react-query'; import { useDeleteActivity } from '../hooks/useDeleteActivity'; import Popup from '@/components/Popup'; -import { toast } from 'sonner'; import { TitleProps } from '@/types/activityDetailType'; function Title({ diff --git a/src/components/DatePicker/CalendarBody.tsx b/src/components/DatePicker/CalendarBody.tsx index a72d761..27c8f3b 100644 --- a/src/components/DatePicker/CalendarBody.tsx +++ b/src/components/DatePicker/CalendarBody.tsx @@ -2,6 +2,7 @@ import type dayjs from 'dayjs'; import { CalendarBodyProps } from '@/types/datePickerTypes'; +import cn from '@/lib/cn'; export default function CalendarBody({ viewDate, @@ -51,36 +52,43 @@ export default function CalendarBody({ ); diff --git a/src/components/FloatingBox/PriceDisplay.tsx b/src/components/FloatingBox/PriceDisplay.tsx index c3e8953..60620f1 100644 --- a/src/components/FloatingBox/PriceDisplay.tsx +++ b/src/components/FloatingBox/PriceDisplay.tsx @@ -8,7 +8,7 @@ export default function PriceDisplay({ price }: { price: number }) {

-
+
: 예약 가능 일자