diff --git a/package-lock.json b/package-lock.json index be925ca..2765c46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@tanstack/react-query-devtools": "^5.84.1", "axios": "^1.11.0", "clsx": "^2.1.1", + "lodash": "^4.17.21", "lottie-react": "^2.4.1", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -27,6 +28,7 @@ "@eslint/js": "^9.29.0", "@svgr/cli": "^8.1.0", "@tailwindcss/vite": "^4.1.11", + "@types/lodash": "^4.17.20", "@types/node": "^24.0.7", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", @@ -2321,6 +2323,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "24.1.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", @@ -4557,6 +4566,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index d79e787..dad3976 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@tanstack/react-query-devtools": "^5.84.1", "axios": "^1.11.0", "clsx": "^2.1.1", + "lodash": "^4.17.21", "lottie-react": "^2.4.1", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -29,6 +30,7 @@ "@eslint/js": "^9.29.0", "@svgr/cli": "^8.1.0", "@tailwindcss/vite": "^4.1.11", + "@types/lodash": "^4.17.20", "@types/node": "^24.0.7", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", diff --git a/src/api/image/image.api.ts b/src/api/image/image.api.ts index 7e21695..0dd8894 100644 --- a/src/api/image/image.api.ts +++ b/src/api/image/image.api.ts @@ -36,4 +36,4 @@ const uploadToS3 = async (url: string, file: File): Promise => { }); }; -export { getPresignedUrls, uploadToS3 }; +export { getPresignedUrls, uploadToS3 }; \ No newline at end of file diff --git a/src/api/profile/profile.api.ts b/src/api/profile/profile.api.ts index 43e8848..f4b9817 100644 --- a/src/api/profile/profile.api.ts +++ b/src/api/profile/profile.api.ts @@ -11,4 +11,4 @@ export const getUserProfile = async (): Promise => { console.error('프로필 로딩 에러:', apiError); throw apiError; } -}; +}; \ No newline at end of file diff --git a/src/api/review/review.ts b/src/api/review/review.ts deleted file mode 100644 index 5674837..0000000 --- a/src/api/review/review.ts +++ /dev/null @@ -1,17 +0,0 @@ -import api from '../api'; -import type { ApiResponse } from '@/types/api-response'; - -export interface ReviewCreateRequest { - seatIds: string[]; - title: string; - movieTitle: string; - rating: number; - content: string; - hashtags: number[]; - imageUrl: string[]; -} - -export const postReview = async (data: ReviewCreateRequest) => { - const res = await api.post>('/reviews', data); - return res.data.data; -}; diff --git a/src/api/user/userEdit.api.ts b/src/api/user/userEdit.api.ts new file mode 100644 index 0000000..99b10bc --- /dev/null +++ b/src/api/user/userEdit.api.ts @@ -0,0 +1,10 @@ +import api from '@/api/api'; +import type { ApiResponse } from '@/types/api-response'; +import type { UpdateUserProfileRequest, UserProfileResponse } from '@/types/userEdit'; + +export const updateUserProfile = async ( + data: UpdateUserProfileRequest +): Promise => { + const response = await api.patch>('/profile', data); + return response.data.data; +}; \ No newline at end of file diff --git a/src/assets/index.tsx b/src/assets/index.tsx index 63cd2b2..760f6a1 100644 --- a/src/assets/index.tsx +++ b/src/assets/index.tsx @@ -88,9 +88,9 @@ export { SoundIcon, EnvironmentIcon, CompanionIcon, - TicketAlt, SmileIcon, GalleryProfileIcon, + TicketAlt, DolbyImage, ImaxImage, HomeBanner, diff --git a/src/components/common/ImagePreview/ImagePreviewItem.tsx b/src/components/common/ImagePreview/ImagePreviewItem.tsx index 6798ef7..e02a3a3 100644 --- a/src/components/common/ImagePreview/ImagePreviewItem.tsx +++ b/src/components/common/ImagePreview/ImagePreviewItem.tsx @@ -47,4 +47,4 @@ export default function ImagePreviewItem({ )} ); -} +} \ No newline at end of file diff --git a/src/components/index.tsx b/src/components/index.tsx index 01b55ec..773817c 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -70,4 +70,3 @@ export { TheaterList, Loading, }; - diff --git a/src/constants/theater.ts b/src/constants/theater.ts new file mode 100644 index 0000000..e63ed29 --- /dev/null +++ b/src/constants/theater.ts @@ -0,0 +1,15 @@ +export const THEATER_ID_MAP: Record = { + 'CGV 용산': '13018', + '메가박스 성수': '13019', + 'CGV 강남': '13020', + '롯데시네마 홍대': '13021', + '메가박스 코엑스': '13022', +}; + +export const THEATER_NAME_MAP: Record = { + '13018': 'CGV 용산', + '13019': '메가박스 성수', + '13020': 'CGV 강남', + '13021': '롯데시네마 홍대', + '13022': '메가박스 코엑스', +}; \ No newline at end of file diff --git a/src/hooks/mutations/usePresignedUrlMutation.ts b/src/hooks/mutations/usePresignedUrlMutation.ts index d7a2ead..eb18448 100644 --- a/src/hooks/mutations/usePresignedUrlMutation.ts +++ b/src/hooks/mutations/usePresignedUrlMutation.ts @@ -7,4 +7,4 @@ export const usePresignedUrlMutation = () => { return useMutation({ mutationFn: ({ fileNames }) => getPresignedUrls(fileNames), }); -}; +}; \ No newline at end of file diff --git a/src/hooks/mutations/useUploadToS3Mutation.ts b/src/hooks/mutations/useUploadToS3Mutation.ts index 99d1913..f19b53c 100644 --- a/src/hooks/mutations/useUploadToS3Mutation.ts +++ b/src/hooks/mutations/useUploadToS3Mutation.ts @@ -11,4 +11,4 @@ export const useUploadToS3Mutation = () => { return useMutation({ mutationFn: ({ url, file }) => uploadToS3(url, file), }); -}; +}; \ No newline at end of file diff --git a/src/hooks/useImageUpload.ts b/src/hooks/useImageUpload.ts index c07400f..cd35cab 100644 --- a/src/hooks/useImageUpload.ts +++ b/src/hooks/useImageUpload.ts @@ -51,4 +51,4 @@ export function useImgUpload(maxCount: number = 5) { isMax, selectedFiles: images, }; -} +} \ No newline at end of file diff --git a/src/hooks/useS3UploadFlow.ts b/src/hooks/useS3UploadFlow.ts index d130906..4b33d66 100644 --- a/src/hooks/useS3UploadFlow.ts +++ b/src/hooks/useS3UploadFlow.ts @@ -68,4 +68,4 @@ export const useS3UploadFlow = async ( // }; // return { uploadImagesToS3 }; -// }; +// }; \ No newline at end of file diff --git a/src/pages/my/CinemaChoice.tsx b/src/pages/my/CinemaChoice.tsx index cbb5f40..84fdfb5 100644 --- a/src/pages/my/CinemaChoice.tsx +++ b/src/pages/my/CinemaChoice.tsx @@ -1,7 +1,8 @@ import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useLocation } from 'react-router-dom'; import { Button, Header, ToggleTab } from '@/components'; import type { CinemaFormat, CinemaType } from '@/types/onboarding'; +import { THEATER_ID_MAP } from '@/constants/theater'; const IMAX_THEATERS: CinemaType[] = ['CGV 용산', '메가박스 성수']; const DOLBY_CINEMA_THEATERS: CinemaType[] = ['CGV 강남', '롯데시네마 홍대', '메가박스 코엑스']; @@ -15,6 +16,8 @@ const MAX_SELECTABLE_THEATERS = 2; export default function CinemaChoice() { const navigate = useNavigate(); + const location = useLocation(); + const [selectedTheaters, setSelectedTheaters] = useState([]); const [activeFormat, setActiveFormat] = useState('Dolby'); @@ -32,13 +35,18 @@ export default function CinemaChoice() { }; const handleConfirmSelection = () => { - console.log('선택된 영화관:', selectedTheaters); - navigate(-1); + const auditoriumIds = selectedTheaters.map((name) => THEATER_ID_MAP[name]); + navigate('/my/profile-edit', { + state: { + auditoriums: auditoriumIds, + nickname: location.state?.nickname, + genres: location.state?.genres, + }, + }); }; const handleFormatSelect = (format: string) => { - setActiveFormat(format as CinemaFormat); - setSelectedTheaters([]); + setActiveFormat(format as CinemaFormat); // ✅ 선택만 바꾸고, 선택 목록 유지 }; const currentTheaters = THEATERS_BY_FORMAT[activeFormat]; @@ -64,10 +72,9 @@ export default function CinemaChoice() { { label: 'Dolby Cinema', value: 'Dolby' }, ]} selected={activeFormat} - onSelect={(selectedValue) => handleFormatSelect(selectedValue)} + onSelect={handleFormatSelect} /> - {/* 영화관 목록 */}
{currentTheaters.map((theater) => ( + { + resetImages(); + addImages(e.target.files); + }} + /> + +
+ {previewUrls.length > 0 ? ( + + ) : ( + + )} +
+
-
- - {/* 즐겨찾는 영화관 섹션 */} -
- {/* Footer */} -