Skip to content

Comments

fix : 중간모임 카테고리 & 환승경로 수정#43

Merged
kangdy25 merged 3 commits intomainfrom
feature/QA-midpoint-ui
Feb 19, 2026
Merged

fix : 중간모임 카테고리 & 환승경로 수정#43
kangdy25 merged 3 commits intomainfrom
feature/QA-midpoint-ui

Conversation

@kim3360
Copy link
Member

@kim3360 kim3360 commented Feb 19, 2026

🚀 중간모임 카테고리 & 환승경로 수정

📝 변경사항

  • hot === true인 장소에 "[모임 목적]이 많은 장소" 표시
  • 순위에 따른 카테고리 텍스트 표시:
    • 1순위: "밍글링 추천 1위"
    • 2순위: "밍글링 추천 2위"
    • hot === true이면서 1순위: "밍글링 추천 1위 · [모임목적]이 많은 장소"
    • hot === true이면서 2순위: "밍글링 추천 2위 · [모임목적]이 많은 장소"

환승 경로 모달 UI 개선

  • 시작역(startStation)과 환승역(transferPathstation) 값으로 경로 표시
  • 하차 위 화살표 추가 및 중복 제거
  • 환승역이 없을 때 시작역 아래 화살표 제거

✅ 체크리스트

  • 코드 리뷰를 받았습니다
  • 테스트를 완료했습니다
  • 린터 에러가 없습니다
  • 타입 에러가 없습니다
  • 브라우저에서 테스트를 완료했습니다
  • 모바일에서 테스트를 완료했습니다 (해당되는 경우)

📸 스크린샷

UI 변경 사항이 있다면 이미지를 드래그해서 넣어주세요!

💬 리뷰어 전달사항

  • 리뷰어가 특별히 확인해야 할 사항이 있다면 적어주세요.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 인기 검색 결과에 대한 순위 표시 기능 추가 (상위 2위까지 특별 포맷 적용)
    • 공유 버튼을 모달 형식으로 개선하여 더 나은 공유 경험 제공
    • 환승 경로 시각화 개선으로 경로 정보 표시 명확화
  • UI/UX 개선

    • 결과 페이지 헤더 레이아웃 조정
    • 인라인 공유 버튼 제거 및 하단 공유 버튼으로 통합

@vercel
Copy link

vercel bot commented Feb 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mingling-frontend Ready Ready Preview, Comment Feb 19, 2026 2:50pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

워크스루

결과 페이지에서 '핫' 상태 속성을 추가하여 카테고리 텍스트 렌더링 로직을 확장했고, 헤더 UI 레이아웃을 조정하여 공유 버튼 위치를 변경했으며, 전송 모달의 경로 단계 계산 로직을 제거하고 전송 경로 세그먼트 렌더링으로 대체했습니다.

변경사항

주제 / 파일(들) 요약
결과 페이지 카테고리 및 헤더 UI
app/result/[id]/page.tsx
getCategoryText 함수 서명을 확장하여 hotrank 매개변수를 추가하고 핫-랭크 결과(1위/2위)에 대한 조건부 서식을 도입했습니다. 헤더 레이아웃을 justify-between에서 갭 기반 레이아웃으로 변경하고, 인라인 공유 버튼을 제거한 후 SHARE 모달을 여는 공유 액션 버튼으로 대체했습니다.
API 타입 정의
types/api.ts
MidpointData 인터페이스에 hot: boolean 속성을 추가하여 중간점 응답 데이터 구조를 확장했습니다.
전송 모달 렌더링 로직
components/modal/transferModal.tsx
extractRouteSteps 헬퍼 함수를 제거하고 route.startStationLine, route.startStation, 그리고 route.transferPath 조건부 렌더링을 사용하도록 변경했습니다. 전송 경로 세그먼트를 라인 배지 및 방향 화살표와 함께 렌더링하도록 업데이트했습니다.

예상 코드 리뷰 소요 시간

🎯 3 (중간 난이도) | ⏱️ ~20분

관련 가능성 있는 PR

제안 검수자

  • kangdy25
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 명확하게 요약하고 있습니다. 중간모임 카테고리와 환승경로 수정이라는 핵심 변경사항을 간결하게 표현하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 있으며, 변경사항이 상세히 기술되어 있고 체크리스트도 완료되었습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/QA-midpoint-ui

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
components/modal/transferModal.tsx (1)

162-226: 좌측 배지/화살표 열과 우측 역 이름 열의 정렬이 어긋날 수 있습니다.

좌측 열(gap-[10px])에는 배지 + 화살표가 포함되어 항목당 높이가 우측 열(gap-[30px])의 텍스트 항목보다 커집니다. 환승이 많아질수록 좌우 정렬 드리프트가 발생할 수 있습니다.

각 "행"을 하나의 flex row로 묶어 좌측 배지와 우측 역 이름을 같은 컨테이너에 배치하면 정렬 문제를 근본적으로 해결할 수 있습니다. 현재 구조에서는 환승 1~2개 정도에서는 크게 눈에 띄지 않을 수 있지만, 환승이 많아지면 문제가 됩니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/modal/transferModal.tsx` around lines 162 - 226, The left
badges/arrow column and right station-name column are rendered as separate
stacked columns causing vertical misalignment when items have different heights;
refactor the JSX in transferModal.tsx so each logical row (start station, each
transfer, final drop-off) is rendered as a single flex row container that
contains the left badge/arrow block and the right station-name block together
(i.e., move the startStation, route.transferPath.map and endStation into a
single map/sequence that yields <div className="flex items-center ..."> rows),
keep existing helpers like getLineBadgeStyle and the train/down Image usages,
and ensure consistent item spacing (use items-center and a single gap value) so
left and right columns stay aligned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/result/`[id]/page.tsx:
- Around line 142-150: The fallback branch that returns '밍글링 추천 1위' when
!category incorrectly applies to items with rank >= 3; update the logic that
produces the label (the branch checking rank === 1, rank === 2, and else if
(!category)) so the !category case respects rank: either check !category earlier
and compute the label from rank (e.g. return `밍글링 추천 ${rank}위` for rank >= 3) or
change the else if (!category) to include rank checks (e.g. else if (!category
&& rank <= 2) ... else return `밍글링 추천 ${rank}위`), ensuring rank, category and
the exact returned string literals are adjusted accordingly.
- Around line 116-156: The function getCategoryText currently uses a hardcoded
purposeText ('[모임 목적]') instead of the actual category; update getCategoryText
to use the category parameter (with a safe fallback when category is undefined)
for all text construction and for the jongseong check, e.g., compute lastChar
and hasJongseong from category (or from a default like '장소' if category is
missing), then use `${category}${hasJongseong ? '이' : '가'} 많은 장소` and include
that computed purposeTextWithPostfix in the hot/rank branches; ensure you keep
the existing special-case returns (e.g., when rank 1/2 or hot) but replace any
occurrence of the placeholder with the actual category and add a null/empty
guard so undefined category still returns the intended default ('밍글링 추천 1위' or a
sensible phrase).

---

Nitpick comments:
In `@components/modal/transferModal.tsx`:
- Around line 162-226: The left badges/arrow column and right station-name
column are rendered as separate stacked columns causing vertical misalignment
when items have different heights; refactor the JSX in transferModal.tsx so each
logical row (start station, each transfer, final drop-off) is rendered as a
single flex row container that contains the left badge/arrow block and the right
station-name block together (i.e., move the startStation, route.transferPath.map
and endStation into a single map/sequence that yields <div className="flex
items-center ..."> rows), keep existing helpers like getLineBadgeStyle and the
train/down Image usages, and ensure consistent item spacing (use items-center
and a single gap value) so left and right columns stay aligned.

Comment on lines +116 to 156
const getCategoryText = (
category: string | undefined,
hot: boolean | undefined,
rank: number,
): string => {
const purposeText = '[모임 목적]';
const lastChar = purposeText.charCodeAt(purposeText.length - 1);
const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
const purposeTextWithPostfix = `${purposeText}${hasJongseong ? '이' : '가'} 많은 장소`;


if (hot === true && rank === 1) {
return `밍글링 추천 1위 · ${purposeTextWithPostfix}`;
}


else if (hot === true && rank === 2) {
return `밍글링 추천 2위 · ${purposeTextWithPostfix}`;
}


else if (hot === true) {
return purposeTextWithPostfix;
}


else if (rank === 1) {
return '밍글링 추천 1위';
}

else if (rank === 2) {
return '밍글링 추천 2위';
}

else if (!category) return '밍글링 추천 1위';

// 카테고리 종성에 따라 "이/가"를 다르게 렌더링
const lastChar = category.charCodeAt(category.length - 1);
const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
return `${category}${hasJongseong ? '이' : '가'} 많은 장소`;
const categoryLastChar = category.charCodeAt(category.length - 1);
const categoryHasJongseong = (categoryLastChar - 0xac00) % 28 !== 0;
return `${category}${categoryHasJongseong ? '이' : '가'} 많은 장소`;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

purposeText에 실제 카테고리 값 대신 리터럴 플레이스홀더 '[모임 목적]'이 하드코딩되어 있습니다.

PR 명세에서 [모임 목적]은 실제 모임 목적(예: "카페", "술집")으로 치환되어야 할 플레이스홀더입니다. 현재 코드는 이 문자열을 그대로 UI에 노출하므로, 사용자에게 "[모임 목적]이 많은 장소"라는 의미 없는 텍스트가 표시됩니다.

category 파라미터를 활용하여 실제 카테고리 값으로 텍스트를 생성해야 합니다. 또한 '[모임 목적]'의 마지막 문자가 ']'(비한글)이므로 종성 판별 로직도 의도와 다른 결과를 산출합니다.

🐛 수정 제안: category 파라미터를 활용한 수정
   const getCategoryText = (
     category: string | undefined,
     hot: boolean | undefined,
     rank: number,
   ): string => {
-    const purposeText = '[모임 목적]';
-    const lastChar = purposeText.charCodeAt(purposeText.length - 1);
-    const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
-    const purposeTextWithPostfix = `${purposeText}${hasJongseong ? '이' : '가'} 많은 장소`;
+    const getPurposeTextWithPostfix = (text: string) => {
+      const lastChar = text.charCodeAt(text.length - 1);
+      const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
+      return `${text}${hasJongseong ? '이' : '가'} 많은 장소`;
+    };
+
+    const purposeTextWithPostfix = category
+      ? getPurposeTextWithPostfix(category)
+      : '인기 많은 장소';
 
     if (hot === true && rank === 1) {
       return `밍글링 추천 1위 · ${purposeTextWithPostfix}`;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getCategoryText = (
category: string | undefined,
hot: boolean | undefined,
rank: number,
): string => {
const purposeText = '[모임 목적]';
const lastChar = purposeText.charCodeAt(purposeText.length - 1);
const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
const purposeTextWithPostfix = `${purposeText}${hasJongseong ? '이' : '가'} 많은 장소`;
if (hot === true && rank === 1) {
return `밍글링 추천 1위 · ${purposeTextWithPostfix}`;
}
else if (hot === true && rank === 2) {
return `밍글링 추천 2위 · ${purposeTextWithPostfix}`;
}
else if (hot === true) {
return purposeTextWithPostfix;
}
else if (rank === 1) {
return '밍글링 추천 1위';
}
else if (rank === 2) {
return '밍글링 추천 2위';
}
else if (!category) return '밍글링 추천 1위';
// 카테고리 종성에 따라 "이/가"를 다르게 렌더링
const lastChar = category.charCodeAt(category.length - 1);
const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
return `${category}${hasJongseong ? '이' : '가'} 많은 장소`;
const categoryLastChar = category.charCodeAt(category.length - 1);
const categoryHasJongseong = (categoryLastChar - 0xac00) % 28 !== 0;
return `${category}${categoryHasJongseong ? '이' : '가'} 많은 장소`;
};
const getCategoryText = (
category: string | undefined,
hot: boolean | undefined,
rank: number,
): string => {
const getPurposeTextWithPostfix = (text: string) => {
const lastChar = text.charCodeAt(text.length - 1);
const hasJongseong = (lastChar - 0xac00) % 28 !== 0;
return `${text}${hasJongseong ? '이' : '가'} 많은 장소`;
};
const purposeTextWithPostfix = category
? getPurposeTextWithPostfix(category)
: '인기 많은 장소';
if (hot === true && rank === 1) {
return `밍글링 추천 1위 · ${purposeTextWithPostfix}`;
}
else if (hot === true && rank === 2) {
return `밍글링 추천 2위 · ${purposeTextWithPostfix}`;
}
else if (hot === true) {
return purposeTextWithPostfix;
}
else if (rank === 1) {
return '밍글링 추천 1위';
}
else if (rank === 2) {
return '밍글링 추천 2위';
}
else if (!category) return '밍글링 추천 1위';
// 카테고리 종성에 따라 "이/가"를 다르게 렌더링
const categoryLastChar = category.charCodeAt(category.length - 1);
const categoryHasJongseong = (categoryLastChar - 0xac00) % 28 !== 0;
return `${category}${categoryHasJongseong ? '이' : '가'} 많은 장소`;
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/result/`[id]/page.tsx around lines 116 - 156, The function
getCategoryText currently uses a hardcoded purposeText ('[모임 목적]') instead of
the actual category; update getCategoryText to use the category parameter (with
a safe fallback when category is undefined) for all text construction and for
the jongseong check, e.g., compute lastChar and hasJongseong from category (or
from a default like '장소' if category is missing), then use
`${category}${hasJongseong ? '이' : '가'} 많은 장소` and include that computed
purposeTextWithPostfix in the hot/rank branches; ensure you keep the existing
special-case returns (e.g., when rank 1/2 or hot) but replace any occurrence of
the placeholder with the actual category and add a null/empty guard so undefined
category still returns the intended default ('밍글링 추천 1위' or a sensible phrase).

Comment on lines +142 to +150
else if (rank === 1) {
return '밍글링 추천 1위';
}

else if (rank === 2) {
return '밍글링 추천 2위';
}

else if (!category) return '밍글링 추천 1위';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

rank >= 3이고 category가 없는 경우 '밍글링 추천 1위'로 폴백됩니다.

hot이 false이고 rank가 3 이상일 때, category도 없으면 Line 150의 else if (!category) 분기에 도달하여 '밍글링 추천 1위'를 반환합니다. Top3 결과에서 3번째 항목에 "1위" 라벨이 표시될 수 있습니다.

기존 코드에서도 동일한 동작이었으나, 이번에 rank 기반 로직을 추가했으므로 함께 수정하는 것이 좋겠습니다.

🛡️ 수정 제안
     else if (rank === 2) {
       return '밍글링 추천 2위';
     }
 
-    else if (!category) return '밍글링 추천 1위';
+    else if (!category) return `밍글링 추천 ${rank}위`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
else if (rank === 1) {
return '밍글링 추천 1위';
}
else if (rank === 2) {
return '밍글링 추천 2위';
}
else if (!category) return '밍글링 추천 1위';
else if (rank === 1) {
return '밍글링 추천 1위';
}
else if (rank === 2) {
return '밍글링 추천 2위';
}
else if (!category) return `밍글링 추천 ${rank}위`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/result/`[id]/page.tsx around lines 142 - 150, The fallback branch that
returns '밍글링 추천 1위' when !category incorrectly applies to items with rank >= 3;
update the logic that produces the label (the branch checking rank === 1, rank
=== 2, and else if (!category)) so the !category case respects rank: either
check !category earlier and compute the label from rank (e.g. return `밍글링 추천
${rank}위` for rank >= 3) or change the else if (!category) to include rank
checks (e.g. else if (!category && rank <= 2) ... else return `밍글링 추천
${rank}위`), ensuring rank, category and the exact returned string literals are
adjusted accordingly.

@kangdy25 kangdy25 merged commit b2088c7 into main Feb 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants