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
74 changes: 33 additions & 41 deletions app/meeting/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ export default function Page() {
router.push(`/result/${id}`);
};

// ⭐ API에서 받은 내 출발지 정보를 selectedStation에 반영 (초기화 시 한 번만)
useEffect(() => {
if (
meetingData?.data?.participants &&
Expand All @@ -143,56 +142,49 @@ export default function Page() {
if (myData?.stationName) {
setTimeout(() => {
setSelectedStation(myData.stationName);
hasInitializedRef.current = true; // 초기화 완료
hasInitializedRef.current = true;
}, 0);
} else {
hasInitializedRef.current = true; // 데이터 없어도 초기화 완료
hasInitializedRef.current = true;
}
}
}, [meetingData, myName]);

const myParticipant = useMemo(() => {
if (!selectedStation || !myName) return null;

const info = STATION_DATA.find((s) => s.name === selectedStation);
if (!info) return null;

return {
id: 'me',
name: myName,
station: info.name,
line: info.line,
latitude: info.latitude,
longitude: info.longitude,
status: 'done',
hexColor: '#000000',
};
}, [selectedStation, myName]);

const allParticipants = useMemo(() => {
if (!myName) return [];

const serverParticipants = meetingData?.data.participants || [];

const others = serverParticipants
.filter((p) => p.userName !== myName)
.map((p, index) => {
const stationInfo = STATION_DATA.find((s) => s.name === p.stationName);

return {
id: `other-${index}`,
name: p.userName,
station: p.stationName,
line: stationInfo?.line ?? '미확인',
latitude: p.latitude,
longitude: p.longitude,
status: 'done',
hexColor: getRandomHexColor(p.userName || p.stationName || `user-${index}`),
};
});
const participantsWithColor = serverParticipants.map((p, index) => {
const stationInfo = STATION_DATA.find((s) => s.name === p.stationName);

return {
id: p.userName === myName ? 'me' : `other-${index}`,
name: p.userName,
station: p.stationName,
line: stationInfo?.line ?? '미확인',
latitude: p.latitude,
longitude: p.longitude,
status: 'done',
hexColor: getRandomHexColor(p.userName, id),
};
});

const myParticipant = participantsWithColor.find((p) => p.name === myName);
const others = participantsWithColor.filter((p) => p.name !== myName);

if (myParticipant && selectedStation) {
const info = STATION_DATA.find((s) => s.name === selectedStation);
if (info) {
myParticipant.station = info.name;
myParticipant.line = info.line;
myParticipant.latitude = info.latitude;
myParticipant.longitude = info.longitude;
}
}

return myParticipant ? [myParticipant, ...others] : others;
}, [meetingData, myParticipant, myName]);
}, [meetingData, selectedStation, myName, id]);

if (!isMounted || !myName) {
return (
Expand Down Expand Up @@ -270,7 +262,7 @@ export default function Page() {
</button>

<div className="flex-1">
<div className="[&::-webkit-scrollbar-thumb]:bg-gray-6 flex h-80 flex-col gap-3.5 overflow-y-scroll pb-5 md:pb-18 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full">
<div className="[&::-webkit-scrollbar-thumb]:bg-gray-6 flex h-80 flex-col gap-3.5 overflow-y-scroll pb-5 md:pb-38 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full">
{allParticipants.length > 0 ? (
allParticipants.map((user) => (
<div
Expand All @@ -283,7 +275,7 @@ export default function Page() {
<div className="flex items-center gap-1.5">
<div
className="flex h-7 w-7 items-center justify-center rounded-full text-xs font-normal text-white"
style={{ backgroundColor: `${user.hexColor}` }}
style={{ backgroundColor: user.hexColor }}
>
{user.name.charAt(0)}
</div>
Expand All @@ -299,7 +291,7 @@ export default function Page() {
</div>
</div>

<div className="group relative right-5 left-5 mb-10 md:absolute md:right-0 md:bottom-0 md:left-0 md:mb-0">
<div className="group relative mb-10 md:absolute md:right-0 md:bottom-0 md:left-0 md:mb-0">
{!isResultEnabled && (
<div className="bg-gray-9 absolute bottom-full left-1/2 mb-2 hidden w-max -translate-x-1/2 rounded px-3 py-1.5 text-xs text-white opacity-0 transition-opacity group-hover:block group-hover:opacity-100">
모든 팀원이 참여해야 결과를 확인할 수 있어요
Expand Down
18 changes: 9 additions & 9 deletions app/recommend/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ function RecommendContent() {
// 모임 정보 조회 (purposes 정보를 가져오기 위해)
const { data: meetingData } = useCheckMeeting(meetingId);

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

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

// 2. API에서 purposes 가져오기 (참여자도 접근 가능)
// 2. API에서 purposes 가져오기
if (meetingData?.data?.purposes && meetingData.data.purposes.length > 0) {
const firstPurpose = meetingData.data.purposes[0];
if (firstPurpose === '회의' || firstPurpose === '친목') {
Expand All @@ -57,11 +57,11 @@ function RecommendContent() {
return null;
}, [meetingId, meetingData, meetingTypeFromUrl]);

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

// 1. URL 쿼리스트링에서 가져오기 (최우선)
// 1. URL 쿼리스트링에서 가져오기
if (categoryFromUrl) {
localStorage.setItem(`meeting_${meetingId}_category`, categoryFromUrl);
return categoryFromUrl;
Expand All @@ -71,7 +71,7 @@ function RecommendContent() {
if (meetingData?.data?.purposes && meetingData.data.purposes.length > 1) {
const subCategory = meetingData.data.purposes[meetingData.data.purposes.length - 1];
if (subCategory) {
// localStorage에도 저장 (다음 접근 시 빠르게 사용)
// localStorage에도 저장
localStorage.setItem(`meeting_${meetingId}_category`, subCategory);
return subCategory;
}
Expand Down Expand Up @@ -140,7 +140,7 @@ function RecommendContent() {
};

const handleOpenKakaoMap = (e: React.MouseEvent, placeUrl?: string) => {
e.stopPropagation(); // 카드 클릭 이벤트 버블링 방지
e.stopPropagation();
if (placeUrl) {
window.open(placeUrl, '_blank', 'noopener,noreferrer');
} else {
Expand Down Expand Up @@ -197,7 +197,7 @@ function RecommendContent() {
onClick={() => setSelectedPlaceId(place.id)}
className={`flex cursor-pointer flex-col gap-2 rounded border p-4 ${
selectedPlaceId === place.id
? 'border-blue-5 border-2' // 선택 시 파란 테두리
? 'border-blue-5 border-2'
: 'border-gray-2 hover:bg-gray-1 bg-white'
}`}
>
Expand Down Expand Up @@ -260,7 +260,7 @@ function RecommendContent() {
</div>
</section>

{/* [RIGHT PANEL] 데스크탑 지도 영역 (새로운 컴포넌트 적용) */}
{/* [RIGHT PANEL] 데스크탑 지도 영역 */}
<section className="bg-gray-1 hidden h-full flex-1 md:block">
<KakaoMapRecommend
className="h-full w-full"
Expand Down
27 changes: 13 additions & 14 deletions app/result/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useCheckMeeting } from '@/hooks/api/query/useCheckMeeting';
import { getMeetingUserId } from '@/lib/storage';
import { useQueryClient } from '@tanstack/react-query';
import Loading from '@/components/loading/loading';
import { getRandomHexColor } from '@/lib/color';

export default function Page() {
const queryClient = useQueryClient();
Expand All @@ -33,7 +34,15 @@ export default function Page() {

return midpointData.data.map((midpoint, index) => {
const { endStation, endStationLine, userRoutes } = midpoint;
const myRoute = userRoutes.find((route) => route.nickname === myNickname);

const routesWithColor = userRoutes.map((route) => {
return {
...route,
hexColor: getRandomHexColor(route.nickname, id),
};
});

const myRoute = routesWithColor.find((route) => route.nickname === myNickname);
const travelTime = myRoute?.travelTime || 0;

const extractLineNumber = (linenumber: string): string => {
Expand Down Expand Up @@ -89,10 +98,10 @@ export default function Page() {
travelTime,
transferPath: myRoute?.transferPath || [],
transferPathLines,
userRoutes,
userRoutes: routesWithColor,
};
});
}, [midpointData, myNickname]);
}, [midpointData, myNickname, id]);

const [selectedResultId, setSelectedResultId] = useState<number>(1);

Expand Down Expand Up @@ -159,7 +168,7 @@ export default function Page() {
case '서해선':
return 'bg-[#5EAC41]';
default:
return 'bg-gray-4';
return 'bg-gray-400';
}
};

Expand All @@ -172,9 +181,7 @@ export default function Page() {
</div>
) : (
<>
{/* [LEFT PANEL] 결과 리스트 영역 */}
<section className="border-gray-1 flex w-full flex-col gap-5 bg-white md:w-77.5 md:gap-3">
{/* 헤더 섹션 */}
<div className="px-5 pt-5 md:p-0">
<div className="flex items-center justify-between">
<div className="text-gray-9 text-[22px] font-semibold tracking-[-1.94%]">
Expand All @@ -191,7 +198,6 @@ export default function Page() {
</div>
</div>

{/* 모바일 전용 지도 영역 */}
{locationResults.length > 0 &&
(() => {
const selectedResult =
Expand All @@ -213,9 +219,7 @@ export default function Page() {
);
})()}

{/* 결과 리스트 & 하단 버튼 */}
<div className="relative mb-10 flex flex-1 flex-col gap-3 px-5 md:mb-0 md:p-0">
{/* 리스트 스크롤 영역 */}
<div className="mb-15 flex-1 overflow-auto">
<div className="flex h-125 min-h-0 flex-col gap-3 pr-1">
{isError || locationResults.length === 0 ? (
Expand All @@ -235,7 +239,6 @@ export default function Page() {
: 'border-gray-2 hover:bg-gray-1'
}`}
>
{/* 카드 헤더: 역 이름 & 시간 */}
<div className="flex items-center justify-between">
<span className="text-gray-10 text-lg font-semibold">
{result.endStation}역
Expand All @@ -248,7 +251,6 @@ export default function Page() {
</span>
</div>

{/* 환승 경로 (호선 아이콘) */}
<div className="text-gray-6 flex items-center gap-3 text-[13px]">
<span>내 환승경로</span>
</div>
Expand Down Expand Up @@ -278,7 +280,6 @@ export default function Page() {
)}
</div>

{/* 모임원 경로 보기 버튼 */}
<button
onClick={(e) => {
e.stopPropagation();
Expand All @@ -301,7 +302,6 @@ export default function Page() {
</div>
</div>

{/* 하단 버튼 */}
<button
onClick={handleModifyStart}
className="bg-blue-5 hover:bg-blue-8 absolute right-5 bottom-0 left-5 h-12 rounded text-lg font-semibold text-white transition-transform active:scale-[0.98] md:right-0 md:left-0"
Expand All @@ -311,7 +311,6 @@ export default function Page() {
</div>
</section>

{/* [RIGHT PANEL] 데스크탑 지도 영역 */}
<section className="bg-gray-1 hidden h-full flex-1 md:block">
{locationResults.length > 0 &&
(() => {
Expand Down
Loading