From 39802a1f98c5044d7d491484bb6f7655546594af Mon Sep 17 00:00:00 2001 From: kimtaewoo <70637743+kim3360@users.noreply.github.com> Date: Sun, 8 Feb 2026 22:32:00 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix=20:=20=EC=83=81=EC=9C=84=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=EC=97=90=20=EB=A7=9E=EC=B6=B0=20?= =?UTF-8?q?=EC=A7=80=EB=8F=84=20=EB=A7=B5=EC=97=90=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=ED=95=98=EC=9C=84=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/create/page.tsx | 2 + app/recommend/page.tsx | 63 ++++++++++++++++++++++++---- components/map/kakaoMapRecommend.tsx | 26 ++++++++++-- types/api.ts | 2 +- 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/app/create/page.tsx b/app/create/page.tsx index 0e3312c..4397c71 100644 --- a/app/create/page.tsx +++ b/app/create/page.tsx @@ -149,6 +149,8 @@ export default function Page() { const category = purposes[purposes.length - 1]; localStorage.setItem(`meeting_${meetingId}_category`, category); } + if (meetingType) { + localStorage.setItem(`meeting_${meetingId}_meetingType`, meetingType); // 링크 공유 페이지 이동 router.push(`/share/${meetingId}`); diff --git a/app/recommend/page.tsx b/app/recommend/page.tsx index 7b5d3de..f64c99e 100644 --- a/app/recommend/page.tsx +++ b/app/recommend/page.tsx @@ -5,6 +5,7 @@ import { useRouter, useSearchParams } from 'next/navigation'; import Image from 'next/image'; import KakaoMapRecommend from '@/components/map/kakaoMapRecommend'; import { useRecommend } from '@/hooks/api/query/useRecommend'; +import { useCheckMeeting } from '@/hooks/api/query/useCheckMeeting'; function RecommendContent() { const router = useRouter(); @@ -21,23 +22,67 @@ function RecommendContent() { // 현재 선택된 장소 ID (기본값: 첫 번째) const [selectedPlaceId, setSelectedPlaceId] = useState(1); - // 선택된 카테고리 (기본값: localStorage의 meetingCategory) - const [selectedCategory, setSelectedCategory] = useState(() => { + // 모임 정보 조회 (purposes 정보를 가져오기 위해) + const { data: meetingData } = useCheckMeeting(meetingId); + + // 상위 카테고리 추출 (API에서 가져오거나 localStorage에서) + const meetingType = useMemo(() => { + if (typeof window === 'undefined') return null; + + // 1. API에서 purposes 가져오기 (참여자도 접근 가능) + if (meetingData?.data?.purposes && meetingData.data.purposes.length > 0) { + const firstPurpose = meetingData.data.purposes[0]; + if (firstPurpose === '회의' || firstPurpose === '친목') { + // localStorage에도 저장 (다음 접근 시 빠르게 사용) localStorage.setItem(`meeting_${meetingId}_meetingType`, firstPurpose); + return firstPurpose as '회의' | '친목'; + } + } + + + const cachedType = localStorage.getItem(`meeting_${meetingId}_meetingType`); + if (cachedType === '회의' || cachedType === '친목') { + return cachedType as '회의' | '친목'; + } + + return null; + }, [meetingId, meetingData]); + + // 하위 카테고리 추출 (API에서 가져오거나 localStorage에서) + const defaultCategory = useMemo(() => { + if (typeof window === 'undefined') return ''; + + // 1. API에서 가져온 purposes의 마지막 값 사용 + if (meetingData?.data?.purposes && meetingData.data.purposes.length > 1) { + const subCategory = meetingData.data.purposes[meetingData.data.purposes.length - 1]; + if (subCategory) { + // localStorage에도 저장 (다음 접근 시 빠르게 사용) + localStorage.setItem(`meeting_${meetingId}_category`, subCategory); + return subCategory; + } + } + const cachedCategory = localStorage.getItem(`meeting_${meetingId}_category`); return cachedCategory || ''; + }, [meetingId, meetingData]); + + const [selectedCategory, setSelectedCategory] = useState(() => { + if (typeof window === 'undefined') return ''; + return localStorage.getItem(`meeting_${meetingId}_category`) || ''; }); + const effectiveCategory = currentCategory; // 카테고리 변경 핸들러 const handleCategoryChange = (category: string) => { setSelectedCategory(category); setSelectedPlaceId(1); // 카테고리 변경 시 첫 번째 장소 선택 + if (typeof window !== 'undefined') { }; - // 장소 추천 API 호출 + // 장소 추천 API 호출 (effectiveCategory 사용 - selectedCategory가 우선) const { data: recommendData, isLoading, isError } = useRecommend({ meetingId, midPlace, - category: selectedCategory, + category: effectiveCategory, page: 1, size: 15, }); @@ -50,7 +95,7 @@ function RecommendContent() { return recommendData.data.placeInfos.map((place, index) => ({ id: index + 1, name: place.placeName, - category: place.categoryGroupName || place.categoryName, + category: place.categoryGroupName, description: place.categoryName, phone: place.phone || '전화번호 없음', address: place.addressName, @@ -98,8 +143,9 @@ function RecommendContent() { places={places} selectedPlaceId={selectedPlaceId} onSelectPlace={setSelectedPlaceId} - selectedCategory={selectedCategory} + selectedCategory={effectiveCategory} onCategoryChange={handleCategoryChange} + meetingType={meetingType} /> @@ -192,8 +238,9 @@ function RecommendContent() { places={places} selectedPlaceId={selectedPlaceId} onSelectPlace={setSelectedPlaceId} - selectedCategory={selectedCategory} - onCategoryChange={setSelectedCategory} + selectedCategory={effectiveCategory} + onCategoryChange={handleCategoryChange} + meetingType={meetingType} /> diff --git a/components/map/kakaoMapRecommend.tsx b/components/map/kakaoMapRecommend.tsx index 9c290c5..01f9e67 100644 --- a/components/map/kakaoMapRecommend.tsx +++ b/components/map/kakaoMapRecommend.tsx @@ -23,13 +23,17 @@ interface KakaoMapRecommendProps { onSelectPlace?: (placeId: number) => void; selectedCategory?: string; onCategoryChange?: (category: string) => void; + meetingType?: '회의' | '친목' | null; } -const CATEGORIES = [ +// 전체 카테고리 목록 +const ALL_CATEGORIES = [ { id: '식당', label: '식당', icon: '/icon/place/restaurant' }, - { id: '놀거리', label: '놀거리', icon: '/icon/place/play' }, + { id: '술집', label: '술집', icon: '/icon/place/bar' }, { id: '카페', label: '카페', icon: '/icon/place/cafe' }, + { id: '놀거리', label: '놀거리', icon: '/icon/place/play' }, { id: '스터디카페', label: '스터디카페', icon: '/icon/place/studycafe' }, + { id: '장소 대여', label: '장소 대여', icon: '/icon/place/rent' }, ]; export default function KakaoMapRecommend({ @@ -41,10 +45,26 @@ export default function KakaoMapRecommend({ selectedPlaceId, selectedCategory = '', onCategoryChange, + meetingType, }: KakaoMapRecommendProps) { // 1. 지도 객체를 state로 관리 (줌 컨트롤 제어용) const [map, setMap] = useState(null); + // 상위 카테고리에 따라 하위 카테고리 필터링 + const categories = useMemo(() => { + if (meetingType === '회의') { + // 회의: 스터디카페, 장소 대여 + return ALL_CATEGORIES.filter((cat) => cat.id === '스터디카페' || cat.id === '장소 대여'); + } else if (meetingType === '친목') { + // 친목: 식당, 술집, 카페, 놀거리 + return ALL_CATEGORIES.filter( + (cat) => cat.id === '식당' || cat.id === '술집' || cat.id === '카페' || cat.id === '놀거리' + ); + } + // meetingType이 없으면 전체 카테고리 표시 + return ALL_CATEGORIES; + }, [meetingType]); + // 선택된 장소 찾기 const selectedPlace = useMemo(() => { if (!selectedPlaceId || places.length === 0) return null; @@ -113,7 +133,7 @@ export default function KakaoMapRecommend({ {/* 상단 카테고리 필터 (Floating) */}
- {CATEGORIES.map((cat) => ( + {categories.map((cat) => (