Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions app/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,17 @@ export default function Page() {
// purposes를 localStorage에 저장 (장소 추천 카테고리로 사용)
const purposes = getPurposes();
if (purposes.length > 0) {
// purposes 배열에서 장소 카테고리 추출 (마지막 값이 일반적으로 장소 카테고리)
const category = purposes[purposes.length - 1];
localStorage.setItem(`meeting_${meetingId}_category`, category);
}
if (meetingType) {
localStorage.setItem(`meeting_${meetingId}_meetingType`, meetingType);
// meetingType 저장 (회의 또는 친목)
if (meetingType) {
localStorage.setItem(`meeting_${meetingId}_meetingType`, meetingType);
}

// 하위 카테고리 저장 (스터디 카페, 식당 등)
if (meetingType === '회의' && selectedLocation) {
localStorage.setItem(`meeting_${meetingId}_category`, selectedLocation);
} else if (meetingType === '친목' && selectedSocialPlace) {
localStorage.setItem(`meeting_${meetingId}_category`, selectedSocialPlace);
}
}

// 링크 공유 페이지 이동
Expand Down Expand Up @@ -312,8 +317,10 @@ export default function Page() {
>
<Image src="/icon/minus.svg" alt="minus" width={20} height={20} />
</button>
<div className={`absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center gap-0.5 text-[15px] leading-[1.6] tracking-[0.144px] ${isParticipantUndecided ? 'text-gray-3' : 'text-gray-8'}`}>
<span>{participantCount}</span>
<div
className={`absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center gap-0.5 text-[15px] leading-[1.6] tracking-[0.144px] ${isParticipantUndecided ? 'text-gray-3' : 'text-gray-8'}`}
>
<span>{participantCount}</span>
<span>명</span>
</div>
<button
Expand Down Expand Up @@ -357,10 +364,14 @@ export default function Page() {
<Image src="/icon/minus.svg" alt="minus" width={20} height={20} />
</button>
<div className="absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 flex-col items-center">
<span className={`text-[12px] leading-[1.334] tracking-[0.3024px] ${isDeadlineFlexible ? 'text-gray-3' : 'text-blue-5'}`}>
<span
className={`text-[12px] leading-[1.334] tracking-[0.3024px] ${isDeadlineFlexible ? 'text-gray-3' : 'text-blue-5'}`}
>
{getDeadlineDate()}
</span>
<div className={`flex items-center gap-0.5 text-[15px] leading-[1.6] tracking-[0.144px] ${isDeadlineFlexible ? 'text-gray-3' : 'text-gray-8'}`}>
<div
className={`flex items-center gap-0.5 text-[15px] leading-[1.6] tracking-[0.144px] ${isDeadlineFlexible ? 'text-gray-3' : 'text-gray-8'}`}
>
<span>{deadlineDays}</span>
<span>일</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/meeting/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export default function Page() {

<button
onClick={handleSubmit}
className="bg-gray-8 right-5 left-5 h-12 cursor-pointer rounded text-lg text-white md:absolute md:right-0 md:bottom-0 md:left-0 md:mb-0"
className="bg-gray-8 right-5 left-5 mb-10 h-12 cursor-pointer rounded text-lg text-white md:absolute md:right-0 md:bottom-0 md:left-0 md:mb-0"
>
결과보기
</button>
Expand Down
62 changes: 43 additions & 19 deletions app/recommend/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { useState, useMemo, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useRouter, useSearchParams } from 'next/navigation';
import Image from 'next/image';
import KakaoMapRecommend from '@/components/map/kakaoMapRecommend';
import { useRecommend } from '@/hooks/api/query/useRecommend';
Expand All @@ -15,6 +15,10 @@ function RecommendContent() {
const lat = searchParams.get('lat');
const lng = searchParams.get('lng');

// 🔥 쿼리스트링에서 카테고리 정보 읽기
const categoryFromUrl = searchParams.get('category') || '';
const meetingTypeFromUrl = searchParams.get('meetingType') as '회의' | '친목' | null;

// 좌표 파싱 (쿼리 파라미터에서 가져오기)
const midPlaceLatitude = lat ? parseFloat(lat) : undefined;
const midPlaceLongitude = lng ? parseFloat(lng) : undefined;
Expand All @@ -25,33 +29,45 @@ function RecommendContent() {
// 모임 정보 조회 (purposes 정보를 가져오기 위해)
const { data: meetingData } = useCheckMeeting(meetingId);

// 상위 카테고리 추출 (API에서 가져오거나 localStorage에서)
// 🔥 상위 카테고리 추출 (우선순위: URL > API > localStorage)
const meetingType = useMemo(() => {
if (typeof window === 'undefined') return null;

// 1. API에서 purposes 가져오기 (참여자도 접근 가능)

// 1. URL 쿼리스트링에서 가져오기 (최우선)
if (meetingTypeFromUrl === '회의' || meetingTypeFromUrl === '친목') {
localStorage.setItem(`meeting_${meetingId}_meetingType`, meetingTypeFromUrl);
return meetingTypeFromUrl;
}

// 2. 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);
localStorage.setItem(`meeting_${meetingId}_meetingType`, firstPurpose);
return firstPurpose as '회의' | '친목';
}
}


// 3. localStorage에서 가져오기
const cachedType = localStorage.getItem(`meeting_${meetingId}_meetingType`);
if (cachedType === '회의' || cachedType === '친목') {
return cachedType as '회의' | '친목';
}

return null;
}, [meetingId, meetingData]);
}, [meetingId, meetingData, meetingTypeFromUrl]);

// 하위 카테고리 추출 (API에서 가져오거나 localStorage에서)
// 🔥 하위 카테고리 추출 (우선순위: URL > API > localStorage)
const defaultCategory = useMemo(() => {
if (typeof window === 'undefined') return '';

// 1. API에서 가져온 purposes의 마지막 값 사용

// 1. URL 쿼리스트링에서 가져오기 (최우선)
if (categoryFromUrl) {
localStorage.setItem(`meeting_${meetingId}_category`, categoryFromUrl);
return categoryFromUrl;
}

// 2. API에서 가져온 purposes의 마지막 값 사용
if (meetingData?.data?.purposes && meetingData.data.purposes.length > 1) {
const subCategory = meetingData.data.purposes[meetingData.data.purposes.length - 1];
if (subCategory) {
Expand All @@ -60,18 +76,22 @@ function RecommendContent() {
return subCategory;
}
}


// 3. localStorage에서 가져오기
const cachedCategory = localStorage.getItem(`meeting_${meetingId}_category`);
return cachedCategory || '';
}, [meetingId, meetingData]);
}, [meetingId, meetingData, categoryFromUrl]);

const [selectedCategory, setSelectedCategory] = useState<string>(() => {
if (typeof window === 'undefined') return '';
return localStorage.getItem(`meeting_${meetingId}_category`) || '';
if (typeof window !== 'undefined') {
const cachedCategory = localStorage.getItem(`meeting_${meetingId}_category`);
if (cachedCategory) return cachedCategory;
}
return '';
});

const currentCategory = selectedCategory || defaultCategory;

const effectiveCategory = currentCategory;

// 카테고리 변경 핸들러
Expand All @@ -84,7 +104,11 @@ function RecommendContent() {
};

// 장소 추천 API 호출 (effectiveCategory 사용 - selectedCategory가 우선)
const { data: recommendData, isLoading, isError } = useRecommend({
const {
data: recommendData,
isLoading,
isError,
} = useRecommend({
meetingId,
midPlace,
category: effectiveCategory,
Expand Down Expand Up @@ -134,7 +158,7 @@ function RecommendContent() {
<button onClick={handleBack} className="flex h-6 w-6 items-center justify-center">
<Image src="/icon/left_chevron.svg" alt="왼쪽 꺾쇠 기호" width={24} height={24} />
</button>
<h2 className="text-gray-9 text-xl font-semibold">{midPlace} 주변 장소 추천</h2>
<h2 className="text-gray-9 text-xl font-semibold">{midPlace} 주변 장소 추천</h2>
</div>

{/* 모바일 전용 지도 (작게 표시) */}
Expand Down
67 changes: 32 additions & 35 deletions app/result/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useOpenModal } from '@/hooks/useOpenModal';
import { useParams, useRouter } from 'next/navigation';
import KakaoMapLine from '@/components/map/kakaoMapLine';
import { useMidpoint } from '@/hooks/api/query/useMidpoint';
import { useCheckMeeting } from '@/hooks/api/query/useCheckMeeting';
import { getMeetingUserId } from '@/lib/storage';

export default function Page() {
Expand All @@ -21,6 +22,7 @@ export default function Page() {
});

const { data: midpointData, isLoading, isError } = useMidpoint(id);
const { data: meetingData } = useCheckMeeting(id);

const locationResults = useMemo(() => {
if (!midpointData?.success || !midpointData.data || !Array.isArray(midpointData.data)) {
Expand All @@ -30,7 +32,7 @@ export default function Page() {
return midpointData.data.map((midpoint, index) => {
const { endStation, endStationLine, userRoutes } = midpoint;
const myRoute = userRoutes.find((route) => route.nickname === myNickname);
const travelTime = myRoute?.travelTime || 0; // 기본값 0 설정
const travelTime = myRoute?.travelTime || 0;

// 호선 번호 추출 함수 (숫자가 있으면 숫자만, 없으면 앞 글자만)
const extractLineNumber = (linenumber: string): string => {
Expand Down Expand Up @@ -63,8 +65,8 @@ export default function Page() {
const lineNumber = extractLineNumber(path.linenumber);
if (lineNumber) {
transferPathLines.push({
display: lineNumber, // 원 안에 표시할 값
text: path.linenumber, // 텍스트로 표시할 원래 값
display: lineNumber,
text: path.linenumber,
});
}
}
Expand All @@ -74,12 +76,11 @@ export default function Page() {
if (endStationLine) {
const endLineNumber = extractLineNumber(endStationLine);
if (endLineNumber) {
// transferPathLines의 마지막 항목과 비교
const lastLine = transferPathLines[transferPathLines.length - 1];
if (lastLine?.display !== endLineNumber) {
transferPathLines.push({
display: endLineNumber, // 원 안에 표시할 값
text: endStationLine, // 텍스트로 표시할 원래 값
display: endLineNumber,
text: endStationLine,
});
}
}
Expand Down Expand Up @@ -112,65 +113,59 @@ export default function Page() {
if (/^\d+$/.test(cleaned)) {
switch (cleaned) {
case '1':
return 'bg-[#004A85]'; // 1호선 파랑
return 'bg-[#004A85]';
case '2':
return 'bg-[#00A23F]'; // 2호선 초록
return 'bg-[#00A23F]';
case '3':
return 'bg-[#ED6C00]'; // 3호선 파랑
return 'bg-[#ED6C00]';
case '4':
return 'bg-[#009BCE]'; // 4호선 파랑
return 'bg-[#009BCE]';
case '5':
return 'bg-[#794698]'; // 5호선 보라색
return 'bg-[#794698]';
case '6':
return 'bg-[#7C4932]'; // 6호선 빨강
return 'bg-[#7C4932]';
case '7':
return 'bg-[#6E7E31]'; // 7호선 초록
return 'bg-[#6E7E31]';
case '8':
return 'bg-[#D11D70]'; // 8호선 빨강
return 'bg-[#D11D70]';
case '9':
return 'bg-[#A49D87]'; // 9호선 회색
return 'bg-[#A49D87]';
default:
return 'bg-gray-400';
}
}

// 전체 호선명으로 처리 (앞 글자가 겹치는 경우 구분)
switch (fullLineName) {
// 수도권 도시철도(경전철)
case '우이신설선':
return 'bg-[#B0CE18]'; // 우이신설 노랑
return 'bg-[#B0CE18]';
case '신림선':
return 'bg-[#5E7DBB]'; // 신림선 하늘
return 'bg-[#5E7DBB]';
case '의정부경전철':
return 'bg-[#F0831E]'; // 의정부경전철 주황
return 'bg-[#F0831E]';
case '용인에버라인':
return 'bg-[#44A436]'; // 용인에버라인 초록
return 'bg-[#44A436]';
case '인천2호선':
return 'bg-[#F4A462]'; // 인천2호선 살색
return 'bg-[#F4A462]';
case '김포골드라인':
return 'bg-[#F4A462]'; // 김포골드라인 금색

// 수도권 도시철도(중전철)
return 'bg-[#F4A462]';
case '경의선':
case '경의중앙선':
return 'bg-[#6AC2B3]'; // 경의중앙선 민트색
return 'bg-[#6AC2B3]';
case '수인분당선':
return 'bg-[#ECA300]'; // 수인분당선 노란색
return 'bg-[#ECA300]';
case '신분당선':
return 'bg-[#B81B30]'; // 신분당선 빨강색
return 'bg-[#B81B30]';
case '인천1호선':
return 'bg-[#B4C7E7]'; // 인천1호선 연한 하늘색
return 'bg-[#B4C7E7]';
case '공항철도':
return 'bg-[#0079AC]'; // 공항철도 파랑색

// 광역철도
return 'bg-[#0079AC]';
case '경춘선':
return 'bg-[#007A62]'; // 경춘선 초록
return 'bg-[#007A62]';
case '경강산':
return 'bg-[#0B318F]'; // 경강산 파란
return 'bg-[#0B318F]';
case '서해선':
return 'bg-[#5EAC41]'; // 서해선 초록

return 'bg-[#5EAC41]';
default:
return 'bg-gray-400';
}
Expand Down Expand Up @@ -214,6 +209,7 @@ export default function Page() {
}}
userRoutes={selectedResult.userRoutes}
meetingId={id}
purposes={meetingData?.data?.purposes}
/>
</div>
);
Expand Down Expand Up @@ -338,6 +334,7 @@ export default function Page() {
}}
userRoutes={selectedResult.userRoutes}
meetingId={id}
purposes={meetingData?.data?.purposes}
/>
);
})()}
Expand Down
Loading