Skip to content

Feat/#105 등록된 식당 검색 페이지에서 메뉴 검색 포함#106

Merged
leeleeleeleejun merged 6 commits intodevelopfrom
feat/#105
Feb 15, 2026
Merged

Feat/#105 등록된 식당 검색 페이지에서 메뉴 검색 포함#106
leeleeleeleejun merged 6 commits intodevelopfrom
feat/#105

Conversation

@leeleeleeleejun
Copy link
Copy Markdown
Member

@leeleeleeleejun leeleeleeleejun commented Feb 15, 2026

#️⃣연관된 이슈

📝작업 내용

등록된 맛집 검색 페이지의 기능을 확장하여 메뉴 이름으로도 맛집을 검색할 수 있도록 개선하고, 이에 맞춰 검색 로직을 리팩토링했습니다.

1. 가게명/메뉴명 검색 전환을 위한 FilterSelector 컴포넌트 구현

2. 검색 로직 리팩토링

  • 검색 타입에 따라 API 호출 함수, Placeholder, label이 동적으로 매핑되도록 구조를 개선했습니다.
  • API_PATH 상수에서 검색 관련 경로를 BY_PLACE와 BY_MENU로 명확히 분리했습니다.

3. UX 개선 (상태 초기화)

key Prop 활용
검색 유형(searchType)이 변경될 때 SearchPage 컴포넌트의 key를 업데이트하여, 이전 검색 결과와 입력값이 자동으로 초기화되도록 처리했습니다.

스크린샷 (선택)

💬리뷰 요구사항(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

Summary by CodeRabbit

  • 새로운 기능

    • 메뉴 기반 검색 추가 — 이름 검색과 함께 메뉴로도 장소 검색 가능
    • 검색 유형 전환용 필터 선택 UI 추가(이름/메뉴)
  • 개선 사항

    • 검색 UI가 검색 유형에 따라 동적으로 업데이트되어 사용성 향상
    • 검색 요청 처리 방식 개선 및 리스트 렌더링 키 안정화로 결과 표시 신뢰성 향상

- 메뉴명 검색 기능 추가로 인한 이름 변경
- api path 및 함수, 스키마 추가
- 가게명/메뉴명 검색 전환을 위한 `FilterSelector` 컴포넌트 구현
- 검색 유형(`searchType`) 변경 시 `SearchPage` 컴포넌트가 리마운트(초기화)되도록 `key` prop 적용
@leeleeleeleejun leeleeleeleejun linked an issue Feb 15, 2026 that may be closed by this pull request
1 task
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 15, 2026

Walkthrough

검색을 이름 기반과 메뉴 기반으로 분리했습니다. 스키마와 서비스 함수가 분리·추가되고 API 경로 상수가 조정되었으며, FilterSelector 컴포넌트와 검색 페이지 로직이 검색 타입 전환을 지원하도록 변경되었습니다. (49자)

Changes

Cohort / File(s) Summary
API 스키마
apps/web/app/_apis/schemas/place.ts
PlaceBySearchSchemaPlaceByNameSearchSchema로 이름 변경, PlaceByMenuSearchSchema 새로 추가 및 관련 타입 추가 (PlaceByNameSearch, PlaceByMenuSearch).
API 서비스
apps/web/app/_apis/services/place.ts
getPlacesBySearchgetPlacesByNameSearch로 변경. 새로 getPlacesByMenuSearch 추가. 반환 타입과 호출하는 경로(BY_NAME / BY_MENU) 업데이트.
경로 상수
apps/web/app/_constants/path.ts
API_PATH.PLACES.SEARCH를 함수에서 { BY_NAME, BY_MENU } 객체로 변경. API_PATH.KAKAO.SEARCH를 파라미터 포함 함수에서 베이스 URL 문자열로 변경.
검색 UI 컴포넌트
apps/web/app/places/search/_components/FilterSelector/FilterSelector.tsx, apps/web/app/places/search/_components/FilterSelector/index.ts
새로운 제네릭 FilterSelector 컴포넌트와 FilterButton, FilterOption 타입 추가 및 인덱스 파일에 re-export 추가.
검색 페이지 및 리스트 렌더링
apps/web/app/places/search/page.tsx, apps/web/app/_components/SearchPage/SearchPage.tsx
검색 타입(NAME/MENU) 전환 로직(TYP E_CONFIG, state) 추가 및 SearchPage 재사용. Search 결과 아이템 key를 place.id + '-' + index로 변경.
Kakao 검색 서비스
apps/web/app/_apis/services/kakaoSearch.ts
쿼리 파라미터를 URL에 직접 포함하지 않고 axios.get(API_PATH.KAKAO.SEARCH, { params: { ... } })로 변경. 인증 헤더 등은 유지.

Sequence Diagram(s)

sequenceDiagram
  participant User as "사용자"
  participant UI as "SearchPage\n+ FilterSelector"
  participant Service as "place service\n(getPlacesByName/MenuSearch)"
  participant Path as "API_PATH"
  participant Backend as "서버 API"
  participant Kakao as "Kakao API"

  User->>UI: 검색어 입력 및 타입 선택
  UI->>UI: 선택에 따라 currentConfig 설정
  UI->>Service: 호출 (keyword)
  Service->>Path: 사용 엔드포인트 결정 (BY_NAME / BY_MENU)
  Service->>Backend: HTTP GET 요청 (검색 API)
  Backend-->>Service: 검색 결과
  Service-->>UI: 변환된 결과 목록
  UI-->>User: 검색 결과 표시

  Note over Service,Kakao: Kakao는 별도 위치 기반 검색에서\nAPI_PATH.KAKAO.SEARCH + params로 호출됨
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 새 길을 갈라 놓았네, 이름과 메뉴로,
버튼 한 번에 길이 바뀌네, 깡충깡충.
FilterSelector가 손잡고 뛰어가니,
결과들이 반짝이며 줄지어 오네. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ⚠️ Unable to check for merge conflicts: Invalid branch name format
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 메뉴 검색 기능 추가라는 주요 변경사항을 명확하게 설명하고 있으며, 실제 변경 내용(메뉴 검색 기능 추가, FilterSelector 컴포넌트 구현, 검색 로직 리팩토링)과 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 feat/#105
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feat/#105
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
apps/web/app/_constants/path.ts (1)

7-17: 다른 경로 상수들도 동일한 패턴으로의 전환을 고려해 볼 수 있습니다.

BY_CATEGORY, BY_RANKING, BY_MAP, NEW.PREVIEW, AUTH.AUTHORIZE 등은 여전히 템플릿 리터럴로 쿼리 파라미터를 직접 삽입하고 있어, SEARCH 경로에서 이전에 지적되었던 동일한 인코딩 위험이 존재합니다. 이번 PR 범위 밖이지만, 향후 일관성을 위해 이들도 기본 URL 문자열 + params 객체 패턴으로 통일하는 것을 권장합니다.

Also applies to: 20-21, 47-48


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.

@leeleeleeleejun leeleeleeleejun self-assigned this Feb 15, 2026
Copy link
Copy Markdown
Contributor

@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: 1

🤖 Fix all issues with AI agents
In `@apps/web/app/_constants/path.ts`:
- Around line 29-32: The SEARCH route builders BY_NAME and BY_MENU insert the
raw keyword into the URL, which breaks on spaces/special chars; update the arrow
functions (SEARCH.BY_NAME and SEARCH.BY_MENU) to wrap the keyword with
encodeURIComponent(...) so getPlacesByNameSearch and getPlacesByMenuSearch
receive a properly encoded query string and avoid malformed URLs.
🧹 Nitpick comments (4)
apps/web/app/places/search/_components/FilterSelector/FilterSelector.tsx (1)

33-55: 접근성: FilterButton에 선택 상태를 시맨틱하게 전달하는 것을 권장합니다.

현재 선택 상태가 시각적 스타일로만 구분됩니다. 스크린 리더 사용자를 위해 aria-pressed를 추가하면 좋겠습니다.

♻️ 제안
    <button
      onClick={onClick}
+     aria-pressed={isSelected}
      className={cn(
apps/web/app/_components/SearchPage/SearchPage.tsx (1)

81-83: 복합 key 사용은 메뉴 검색에서 동일 placeId가 여러 번 나올 수 있어 합리적입니다.

메뉴 검색 결과에서 같은 가게가 다른 메뉴로 중복 노출될 수 있으므로 place.id + '-' + index 조합이 필요합니다. 다만 가능하다면 고유 식별자(예: placeId-menuName 또는 서버에서 제공하는 고유 ID)를 사용하는 것이 index 기반보다 React 재조정(reconciliation)에 유리합니다.

apps/web/app/_apis/schemas/place.ts (1)

46-50: placeId 스키마 정의가 BasePlaceSchema와 중복됩니다.

BasePlaceSchemaplaceId 정의(z.number().transform(String))와 동일한 로직이 반복되고 있습니다. BasePlaceSchema.shape.placeId를 재사용하면 변환 로직 변경 시 한 곳만 수정하면 됩니다.

♻️ 제안
 export const PlaceByMenuSearchSchema = z.object({
-  placeId: z.number().transform(String),
+  placeId: BasePlaceSchema.shape.placeId,
   placeName: z.string(),
   menuName: z.string(),
 })
apps/web/app/places/search/page.tsx (1)

36-44: 메뉴 검색 결과에서 address 필드에 가게명(placeName)을 매핑하고 있습니다.

BasePlace.addressplace.placeName을 넣으면 SearchPlaceListItem이 가게명을 주소처럼 표시하게 됩니다. 의도된 UX라면 괜찮지만, BasePlace 타입의 시맨틱과 맞지 않아 혼란을 줄 수 있습니다.

향후 BasePlacesubtitle 같은 범용 필드를 두거나, 메뉴 검색 전용 리스트 아이템을 만드는 것도 고려해보세요.

}))}
/>
<SearchPage
key={searchType}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

searchType 변경 시 key prop 업데이트로 SearchPage 컴포넌트 새롭게 렌더링
입력값과 결과값 모두 초기화를 위해 추가

- 기존 URL 문자열 결합 방식을 axios `params` 객체 전달 방식으로 변경
- 검색어에 특수문자(&, #, = 등)나 공백이 포함될 경우 URL이 깨지거나 잘못 요청되는 버그 수정
- 자동 URL 인코딩을 통해 안정적인 API 호출 보장
@leeleeleeleejun leeleeleeleejun merged commit b22d6e6 into develop Feb 15, 2026
1 check 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.

[Feature] 등록된 식당 검색 페이지에서 메뉴 검색 포함

1 participant