Skip to content

feat: 모임 의견 취합 Step 2 (불호 입력) 구현 #30

Merged
RookieAND merged 12 commits intofeature/opinion-step-distancefrom
feature/opinion-step-dislike
Jan 27, 2026
Merged

feat: 모임 의견 취합 Step 2 (불호 입력) 구현 #30
RookieAND merged 12 commits intofeature/opinion-step-distancefrom
feature/opinion-step-dislike

Conversation

@RookieAND
Copy link
Collaborator

🎯 PR 제목

[Opinion] Dislike Step 구현 - 싫어하는 음식 선택 기능

📑 작업 상세 내역

1. FoodCategoryButton 컴포넌트 구현

  • 156px 원형 버튼 디자인
  • 음식 카테고리별 아이콘 및 라벨 표시
  • 선택 시 X 아이콘 fade 애니메이션
  • selected/unselected 상태 관리
  • hover/active 스타일 적용

2. Checkbox 컴포넌트 추가

  • Vapor UI 기반 Checkbox 구현
  • Root, Indicator, Label 컴포지션 패턴
  • checked/unchecked 상태 스타일
  • 접근성 라벨 지원

3. DislikeStep 컴포넌트 구현

  • StepIndicator "2/3" 표시
  • StepHeader: "싫어하는 음식 종류를 선택해주세요"
  • FoodCategoryButton 3열 그리드 배치 (한식, 일식, 중식, 양식, 아시안)
  • react-hook-form Controller로 dislikedFoods 배열 관리
  • "상관없음" Checkbox로 선택 초기화 기능
  • "다음" 버튼 (항상 활성화)

4. DislikeStepProps 타입 추가

  • 타입 시스템에 DislikeStepProps export 추가

🙏 리뷰 요청 사항

  • FoodCategoryButton의 원형 디자인과 애니메이션이 디자인 시안과 일치하는지 확인 부탁드립니다
  • 3열 그리드 레이아웃이 모바일 화면에서 적절한지 검토 부탁드립니다

@github-actions github-actions bot added ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 ✨ Feature 기능 개발 labels Jan 25, 2026
@github-actions github-actions bot requested a review from youngminss January 25, 2026 14:21
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @RookieAND, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 사용자가 싫어하는 음식 카테고리를 선택할 수 있도록 모임 의견 취합 기능의 두 번째 단계를 도입합니다. 음식 카테고리 선택을 위한 새로운 UI 컴포넌트와 일반 체크박스를 포함하며, 이들을 싫어하는 음식 선택 단계에 통합하여 폼 관리를 지원하고 사용자 경험을 개선합니다.

Highlights

  • FoodCategoryButton 컴포넌트 구현: 특정 디자인 및 애니메이션을 가진 음식 카테고리 선택 버튼 컴포넌트가 추가되었습니다. 156px 원형 디자인, 아이콘 및 라벨 표시, 선택 시 X 아이콘 fade 애니메이션, 선택/미선택 상태 관리, hover/active 스타일이 적용됩니다.
  • Checkbox 컴포넌트 추가: Vapor UI 기반의 체크박스 컴포넌트가 Root, Indicator, Label 컴포지션 패턴을 사용하여 구현되었습니다. checked/unchecked 상태 스타일과 접근성 라벨을 지원합니다.
  • DislikeStep 컴포넌트 구현: 모임 의견 취합 흐름의 두 번째 단계인 '싫어하는 음식' 선택 기능이 구현되었습니다. StepIndicator '2/3' 표시, '싫어하는 음식 종류를 선택해주세요' 헤더, 3열 그리드 배치된 FoodCategoryButton (한식, 일식, 중식, 양식, 아시안), react-hook-form Controller를 통한 dislikedFoods 배열 관리, '상관없음' 체크박스를 통한 선택 초기화 기능, 항상 활성화된 '다음' 버튼을 포함합니다.
  • DislikeStepProps 타입 추가: 타입 시스템에 DislikeStepProps가 내보내져 DislikeStep 컴포넌트의 props를 정의합니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 PR은 모임 의견 취합 과정의 두 번째 단계인 '불호 음식 선택' 기능을 구현합니다. FoodCategoryButton과 재사용 가능한 Checkbox 컴파운드 컴포넌트가 새롭게 추가되었습니다. 전반적으로 기능 구현은 잘 이루어졌으나, 몇 가지 스타일 가이드 위반 사항이 발견되었습니다. 주로 interface 대신 type 사용, clsx 대신 twJoin 사용, 그리고 디자인 토큰 대신 하드코딩된 값(크기, 간격, 색상)을 사용한 부분들입니다. 각 파일에 구체적인 수정 제안을 포함한 리뷰 코멘트를 남겼으니 확인 부탁드립니다.

Comment on lines +19 to +21
interface LabelProps {
children: ReactNode;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

스타일 가이드(라인 196, 491)에 따라 Props 정의 시 interface 대신 type을 사용해야 합니다.

Suggested change
interface LabelProps {
children: ReactNode;
}
type LabelProps = {
children: ReactNode;
};
References
  1. Prefer type over interface for Props definitions. Don't use interface for Props. (link)

Comment on lines +8 to +13
interface CheckBoxRootProps {
checked: boolean;
disabled?: boolean;
onCheckedChange: (checked: boolean) => void;
children: ReactNode;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

스타일 가이드(라인 196, 491)에 따라 Props 정의 시 interface 대신 type을 사용해야 합니다.

Suggested change
interface CheckBoxRootProps {
checked: boolean;
disabled?: boolean;
onCheckedChange: (checked: boolean) => void;
children: ReactNode;
}
type CheckBoxRootProps = {
checked: boolean;
disabled?: boolean;
onCheckedChange: (checked: boolean) => void;
children: ReactNode;
};
References
  1. Prefer type over interface for Props definitions. Don't use interface for Props. (link)

@RookieAND RookieAND self-assigned this Jan 25, 2026
Copy link
Member

@youngminss youngminss left a comment

Choose a reason for hiding this comment

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

Image

기본 상태값으로 상관없음이 골라져서 다음 버튼이 기본적으로 활성화되어 있더라구
광인이가 알잘딱으로 해놓은건지 ? 디자이너 의도 구현해준건지 궁금하네

@RookieAND RookieAND force-pushed the feature/opinion-step-distance branch from d7445e0 to 5687460 Compare January 27, 2026 10:08
- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles
- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)
- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels
@RookieAND RookieAND force-pushed the feature/opinion-step-dislike branch from 0ae3145 to 04ccd7b Compare January 27, 2026 10:37
@RookieAND
Copy link
Collaborator Author

@youngminss 원래는 알잘딱이었는데 의도한 기능은 아니라고 해서 수정했어!

@RookieAND RookieAND requested a review from youngminss January 27, 2026 11:57
* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
@RookieAND RookieAND merged commit 7ec1e14 into feature/opinion-step-distance Jan 27, 2026
6 checks passed
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rookieBaikGoorm <rookie.baik@goorm.io>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* feat: 모임 생성 완료 페이지 구현

- 완료 페이지 UI 구현 (일러스트레이션, 버튼)
- MeetingCompleteIllustration 컴포넌트 추가 (Figma 시안 기반)
- share util 추가 (Web Share API + 클립보드 fallback)
- 모바일에서만 네이티브 공유 시트 사용 (768px 미만)
- toast success 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: import 경로 수정

* feat: 모임 의견 취합 패널 구성에 필요한 설정 요소 구축 (#27)

* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 랜딩 페이지 구현 및 OG 메타데이터 추가 (#33)

* feat: OG 메타데이터 추가

- title: 요기잇
- description: 다인원을 위한 맛집 추천 서비스
- og:image placeholder 추가 (추후 이미지 적용 시 활성화)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 구현

- LandingPage 컴포넌트 추가
- Layout.Root 활용하여 일관된 레이아웃 적용
- Figma 디자인 기반 UI 구현:
  - 상단 타이틀 및 로고
  - 음식 일러스트레이션 (초밥, 국밥)
  - 하트 아이콘 장식
  - CTA 버튼 (모임 링크 생성 시작)
- 버튼 클릭 시 /gathering/create 페이지로 라우팅
- 랜딩 페이지 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 요소 위치 시안과 동일하게 조정

- 375px 기준 Figma 시안과 동일한 위치로 조정
- 손가락 아이콘 위치를 중앙 하단으로 이동
- 파란색 국밥 카드 회전 각도 15deg 유지
- 하트 아이콘 및 초밥 카드 위치 조정
- 픽셀 값을 Tailwind 스페이싱 유틸리티로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 위치 미세 조정 및 타이포그래피 유틸리티 추가

- 손가락 아이콘 위치를 Tailwind 스페이싱으로 변환
- 하트 아이콘 위치 미세 조정
- heading-18-bd 타이포그래피 유틸리티 추가
- body-18-bd letter-spacing 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: prettier 포맷 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 손가락 아이콘 애니메이션 추가

- motion 라이브러리를 활용한 손가락 아이콘 애니메이션 구현
- 초밥 카드를 가리켰다가 국밥 카드로 돌아오는 반복 애니메이션
- 이미지에 priority 속성 추가하여 LCP 최적화
- router.push를 router.replace로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* fix: location 타입을 optional로 변경

- 장소 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) 구현

- LocationStep 컴포넌트 구현 (placeholder에서 실제 구현으로)
- 장소 선택 UI 구현 (Chip 활용 - 홍대입구역/강남역)
- 토글 방식 선택 (선택된 항목 다시 클릭 시 해제)
- useLocationStepValidation 훅 활용하여 CTA 활성화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: LocationStep 코드 개선

- Chip 컴포넌트를 LOCATION_OPTIONS 배열로 map 렌더링
- watch를 useWatch로 변경하여 리렌더링 최적화
- location 값을 대문자로 변경 (hongdae → HONGDAE, gangnam → GANGNAM)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 완료 페이지 구현 (#26)

* feat: 모임 생성 완료 페이지 구현

- 완료 페이지 UI 구현 (일러스트레이션, 버튼)
- MeetingCompleteIllustration 컴포넌트 추가 (Figma 시안 기반)
- share util 추가 (Web Share API + 클립보드 fallback)
- 모바일에서만 네이티브 공유 시트 사용 (768px 미만)
- toast success 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: import 경로 수정

* feat: 모임 의견 취합 패널 구성에 필요한 설정 요소 구축 (#27)

* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 랜딩 페이지 구현 및 OG 메타데이터 추가 (#33)

* feat: OG 메타데이터 추가

- title: 요기잇
- description: 다인원을 위한 맛집 추천 서비스
- og:image placeholder 추가 (추후 이미지 적용 시 활성화)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 구현

- LandingPage 컴포넌트 추가
- Layout.Root 활용하여 일관된 레이아웃 적용
- Figma 디자인 기반 UI 구현:
  - 상단 타이틀 및 로고
  - 음식 일러스트레이션 (초밥, 국밥)
  - 하트 아이콘 장식
  - CTA 버튼 (모임 링크 생성 시작)
- 버튼 클릭 시 /gathering/create 페이지로 라우팅
- 랜딩 페이지 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 요소 위치 시안과 동일하게 조정

- 375px 기준 Figma 시안과 동일한 위치로 조정
- 손가락 아이콘 위치를 중앙 하단으로 이동
- 파란색 국밥 카드 회전 각도 15deg 유지
- 하트 아이콘 및 초밥 카드 위치 조정
- 픽셀 값을 Tailwind 스페이싱 유틸리티로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 위치 미세 조정 및 타이포그래피 유틸리티 추가

- 손가락 아이콘 위치를 Tailwind 스페이싱으로 변환
- 하트 아이콘 위치 미세 조정
- heading-18-bd 타이포그래피 유틸리티 추가
- body-18-bd letter-spacing 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: prettier 포맷 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 손가락 아이콘 애니메이션 추가

- motion 라이브러리를 활용한 손가락 아이콘 애니메이션 구현
- 초밥 카드를 가리켰다가 국밥 카드로 돌아오는 반복 애니메이션
- 이미지에 priority 속성 추가하여 LCP 최적화
- router.push를 router.replace로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* fix: Chip 컴포넌트 선택 상태 색상을 시안과 일치하도록 수정

- selected 상태의 배경색을 button-primary(#1f2933)에서
  button-secondary(#ff5a3c)로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 2 (날짜 입력) 구현

- DateStep 컴포넌트 구현
  - 숫자만 입력 가능한 날짜 입력 필드 (inputMode="numeric")
  - 자동 yyyy.mm.dd 형식 포맷팅
  - 연도/월/일 유효성 검사 (0으로 시작 방지, 00월/00일 방지 등)
  - 시간대 선택 (점심/저녁) Chip 토글
- useDateStepValidation 훅에 날짜 형식 및 실제 날짜 유효성 검사 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: 날짜 관련 상수 및 유틸 함수 분리

- DATE_PATTERN 상수를 constants/gathering/create로 이동
- formatDateInput, isValidDateFormat 함수를 utils/gathering/create로 이동
- DateStep.tsx, useCreateMeetingForm.ts에서 중복 코드 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: timeSlot 타입을 optional로 변경

- 시간대 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 날짜 입력 필드에 clear 버튼 추가

- showClearButton, onClear prop 활용
- handleDateClear 함수 추가
- handleTimeSlotChange 로직 간소화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refac: 명시적으로 named export

* feat: date-fns를 활용한 날짜 유효성 검사 개선

- date-fns 4.1.0 설치
- isValidDateFormat 함수에서 date-fns의 parse, isValid 사용
- native Date 대신 date-fns로 더 명확한 날짜 검증

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: watch를 useWatch로 변경

- 불필요한 리렌더링 방지를 위해 useWatch 사용
- 지정한 필드만 구독하여 성능 최적화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: isUndefined를 isNil로 변경

- 향후 API 연동 시 null 값 대응을 위해 isNil 사용
- undefined와 null 모두 체크하여 방어적 코드 작성

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: timeSlot 값을 대문자로 변경

- "lunch" | "dinner" → "LUNCH" | "DINNER"
- API 응답값과 일관성 유지를 위한 대문자 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: hasDateError 로직 개선

- 입력 중 에러 표시 방지 (10자리 완성 시에만 검사)
- DATE_PATTERN 대신 isValidDateFormat 사용으로 실제 날짜 유효성 검사
- useDateStepValidation과 검증 로직 통일

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) UI 구현 (#25)

* fix: location 타입을 optional로 변경

- 장소 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) 구현

- LocationStep 컴포넌트 구현 (placeholder에서 실제 구현으로)
- 장소 선택 UI 구현 (Chip 활용 - 홍대입구역/강남역)
- 토글 방식 선택 (선택된 항목 다시 클릭 시 해제)
- useLocationStepValidation 훅 활용하여 CTA 활성화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: LocationStep 코드 개선

- Chip 컴포넌트를 LOCATION_OPTIONS 배열로 map 렌더링
- watch를 useWatch로 변경하여 리렌더링 최적화
- location 값을 대문자로 변경 (hongdae → HONGDAE, gangnam → GANGNAM)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 완료 페이지 구현 (#26)

* feat: 모임 생성 완료 페이지 구현

- 완료 페이지 UI 구현 (일러스트레이션, 버튼)
- MeetingCompleteIllustration 컴포넌트 추가 (Figma 시안 기반)
- share util 추가 (Web Share API + 클립보드 fallback)
- 모바일에서만 네이티브 공유 시트 사용 (768px 미만)
- toast success 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: import 경로 수정

* feat: 모임 의견 취합 패널 구성에 필요한 설정 요소 구축 (#27)

* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 랜딩 페이지 구현 및 OG 메타데이터 추가 (#33)

* feat: OG 메타데이터 추가

- title: 요기잇
- description: 다인원을 위한 맛집 추천 서비스
- og:image placeholder 추가 (추후 이미지 적용 시 활성화)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 구현

- LandingPage 컴포넌트 추가
- Layout.Root 활용하여 일관된 레이아웃 적용
- Figma 디자인 기반 UI 구현:
  - 상단 타이틀 및 로고
  - 음식 일러스트레이션 (초밥, 국밥)
  - 하트 아이콘 장식
  - CTA 버튼 (모임 링크 생성 시작)
- 버튼 클릭 시 /gathering/create 페이지로 라우팅
- 랜딩 페이지 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 요소 위치 시안과 동일하게 조정

- 375px 기준 Figma 시안과 동일한 위치로 조정
- 손가락 아이콘 위치를 중앙 하단으로 이동
- 파란색 국밥 카드 회전 각도 15deg 유지
- 하트 아이콘 및 초밥 카드 위치 조정
- 픽셀 값을 Tailwind 스페이싱 유틸리티로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 위치 미세 조정 및 타이포그래피 유틸리티 추가

- 손가락 아이콘 위치를 Tailwind 스페이싱으로 변환
- 하트 아이콘 위치 미세 조정
- heading-18-bd 타이포그래피 유틸리티 추가
- body-18-bd letter-spacing 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: prettier 포맷 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 손가락 아이콘 애니메이션 추가

- motion 라이브러리를 활용한 손가락 아이콘 애니메이션 구현
- 초밥 카드를 가리켰다가 국밥 카드로 돌아오는 반복 애니메이션
- 이미지에 priority 속성 추가하여 LCP 최적화
- router.push를 router.replace로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>
RookieAND added a commit that referenced this pull request Jan 27, 2026
* style: 기존 컴포넌트 스타일 미적용 수정

* feat: 모임 생성 타입 정의

- CreateMeetingForm 인터페이스 추가
- TimeSlot, Location, CreateMeetingStep 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 폼 및 퍼널 훅 추가

- useCreateMeetingForm: react-hook-form 기반 폼 상태 관리
- usePeopleStepValidation, useDateStepValidation, useLocationStepValidation: 각 step 유효성 검사
- useCreateMeetingFunnel: React state 기반 step 네비게이션 관리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 컴포넌트 추가

- PeopleStep: 인원 선택 (1-10명), 토글 선택/해제 지원
- PeopleCountGrid: 5x2 그리드 버튼 UI
- DateStep: 날짜 선택 (placeholder)
- LocationStep: 장소 선택 (placeholder)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 페이지 구현

- react-hook-form으로 폼 상태 관리
- useCreateMeetingFunnel로 step 네비게이션 관리
- 새로고침 시 항상 step 1부터 시작

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: hooks를 화살표 함수 형태로 변경

- useCreateMeetingForm, usePeopleStepValidation 등 모든 hooks를
  function 선언에서 화살표 함수로 변경
- 스타일 가이드 일관성 준수

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: StepIndicator에서 불필요한 padding 제거

- px-space-24 클래스 제거 (상위 컴포넌트에서 처리)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: PeopleCountGrid 스페이싱 토큰 조정

- gap-sm → gap-3, gap-xs → gap-2로 변경
- deprecated된 spacing 변수 대신 일반 값 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: PeopleStep 코드 스타일 개선

- import 경로를 폴더 경로로 통일 (스타일 가이드 준수)
- function 선언을 화살표 함수로 변경
- gap-xl → gap-6로 스페이싱 조정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refac: undefined 체크 함수 es-toolkit 활용

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 2 (날짜 입력) 구현 (#24)

* fix: Chip 컴포넌트 선택 상태 색상을 시안과 일치하도록 수정

- selected 상태의 배경색을 button-primary(#1f2933)에서
  button-secondary(#ff5a3c)로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 2 (날짜 입력) 구현

- DateStep 컴포넌트 구현
  - 숫자만 입력 가능한 날짜 입력 필드 (inputMode="numeric")
  - 자동 yyyy.mm.dd 형식 포맷팅
  - 연도/월/일 유효성 검사 (0으로 시작 방지, 00월/00일 방지 등)
  - 시간대 선택 (점심/저녁) Chip 토글
- useDateStepValidation 훅에 날짜 형식 및 실제 날짜 유효성 검사 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: 날짜 관련 상수 및 유틸 함수 분리

- DATE_PATTERN 상수를 constants/gathering/create로 이동
- formatDateInput, isValidDateFormat 함수를 utils/gathering/create로 이동
- DateStep.tsx, useCreateMeetingForm.ts에서 중복 코드 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: timeSlot 타입을 optional로 변경

- 시간대 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 날짜 입력 필드에 clear 버튼 추가

- showClearButton, onClear prop 활용
- handleDateClear 함수 추가
- handleTimeSlotChange 로직 간소화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refac: 명시적으로 named export

* feat: date-fns를 활용한 날짜 유효성 검사 개선

- date-fns 4.1.0 설치
- isValidDateFormat 함수에서 date-fns의 parse, isValid 사용
- native Date 대신 date-fns로 더 명확한 날짜 검증

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: watch를 useWatch로 변경

- 불필요한 리렌더링 방지를 위해 useWatch 사용
- 지정한 필드만 구독하여 성능 최적화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: isUndefined를 isNil로 변경

- 향후 API 연동 시 null 값 대응을 위해 isNil 사용
- undefined와 null 모두 체크하여 방어적 코드 작성

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: timeSlot 값을 대문자로 변경

- "lunch" | "dinner" → "LUNCH" | "DINNER"
- API 응답값과 일관성 유지를 위한 대문자 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: hasDateError 로직 개선

- 입력 중 에러 표시 방지 (10자리 완성 시에만 검사)
- DATE_PATTERN 대신 isValidDateFormat 사용으로 실제 날짜 유효성 검사
- useDateStepValidation과 검증 로직 통일

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) UI 구현 (#25)

* fix: location 타입을 optional로 변경

- 장소 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) 구현

- LocationStep 컴포넌트 구현 (placeholder에서 실제 구현으로)
- 장소 선택 UI 구현 (Chip 활용 - 홍대입구역/강남역)
- 토글 방식 선택 (선택된 항목 다시 클릭 시 해제)
- useLocationStepValidation 훅 활용하여 CTA 활성화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: LocationStep 코드 개선

- Chip 컴포넌트를 LOCATION_OPTIONS 배열로 map 렌더링
- watch를 useWatch로 변경하여 리렌더링 최적화
- location 값을 대문자로 변경 (hongdae → HONGDAE, gangnam → GANGNAM)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 완료 페이지 구현 (#26)

* feat: 모임 생성 완료 페이지 구현

- 완료 페이지 UI 구현 (일러스트레이션, 버튼)
- MeetingCompleteIllustration 컴포넌트 추가 (Figma 시안 기반)
- share util 추가 (Web Share API + 클립보드 fallback)
- 모바일에서만 네이티브 공유 시트 사용 (768px 미만)
- toast success 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: import 경로 수정

* feat: 모임 의견 취합 패널 구성에 필요한 설정 요소 구축 (#27)

* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 랜딩 페이지 구현 및 OG 메타데이터 추가 (#33)

* feat: OG 메타데이터 추가

- title: 요기잇
- description: 다인원을 위한 맛집 추천 서비스
- og:image placeholder 추가 (추후 이미지 적용 시 활성화)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 구현

- LandingPage 컴포넌트 추가
- Layout.Root 활용하여 일관된 레이아웃 적용
- Figma 디자인 기반 UI 구현:
  - 상단 타이틀 및 로고
  - 음식 일러스트레이션 (초밥, 국밥)
  - 하트 아이콘 장식
  - CTA 버튼 (모임 링크 생성 시작)
- 버튼 클릭 시 /gathering/create 페이지로 라우팅
- 랜딩 페이지 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 요소 위치 시안과 동일하게 조정

- 375px 기준 Figma 시안과 동일한 위치로 조정
- 손가락 아이콘 위치를 중앙 하단으로 이동
- 파란색 국밥 카드 회전 각도 15deg 유지
- 하트 아이콘 및 초밥 카드 위치 조정
- 픽셀 값을 Tailwind 스페이싱 유틸리티로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 위치 미세 조정 및 타이포그래피 유틸리티 추가

- 손가락 아이콘 위치를 Tailwind 스페이싱으로 변환
- 하트 아이콘 위치 미세 조정
- heading-18-bd 타이포그래피 유틸리티 추가
- body-18-bd letter-spacing 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: prettier 포맷 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 손가락 아이콘 애니메이션 추가

- motion 라이브러리를 활용한 손가락 아이콘 애니메이션 구현
- 초밥 카드를 가리켰다가 국밥 카드로 돌아오는 반복 애니메이션
- 이미지에 priority 속성 추가하여 LCP 최적화
- router.push를 router.replace로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>
@youngminss youngminss removed the ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 label Jan 29, 2026
RookieAND added a commit that referenced this pull request Feb 16, 2026
* style: 기존 컴포넌트 스타일 미적용 수정

* feat: 모임 생성 타입 정의

- CreateMeetingForm 인터페이스 추가
- TimeSlot, Location, CreateMeetingStep 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 폼 및 퍼널 훅 추가

- useCreateMeetingForm: react-hook-form 기반 폼 상태 관리
- usePeopleStepValidation, useDateStepValidation, useLocationStepValidation: 각 step 유효성 검사
- useCreateMeetingFunnel: React state 기반 step 네비게이션 관리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 컴포넌트 추가

- PeopleStep: 인원 선택 (1-10명), 토글 선택/해제 지원
- PeopleCountGrid: 5x2 그리드 버튼 UI
- DateStep: 날짜 선택 (placeholder)
- LocationStep: 장소 선택 (placeholder)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 페이지 구현

- react-hook-form으로 폼 상태 관리
- useCreateMeetingFunnel로 step 네비게이션 관리
- 새로고침 시 항상 step 1부터 시작

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: hooks를 화살표 함수 형태로 변경

- useCreateMeetingForm, usePeopleStepValidation 등 모든 hooks를
  function 선언에서 화살표 함수로 변경
- 스타일 가이드 일관성 준수

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: StepIndicator에서 불필요한 padding 제거

- px-space-24 클래스 제거 (상위 컴포넌트에서 처리)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: PeopleCountGrid 스페이싱 토큰 조정

- gap-sm → gap-3, gap-xs → gap-2로 변경
- deprecated된 spacing 변수 대신 일반 값 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: PeopleStep 코드 스타일 개선

- import 경로를 폴더 경로로 통일 (스타일 가이드 준수)
- function 선언을 화살표 함수로 변경
- gap-xl → gap-6로 스페이싱 조정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refac: undefined 체크 함수 es-toolkit 활용

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 2 (날짜 입력) 구현 (#24)

* fix: Chip 컴포넌트 선택 상태 색상을 시안과 일치하도록 수정

- selected 상태의 배경색을 button-primary(#1f2933)에서
  button-secondary(#ff5a3c)로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 2 (날짜 입력) 구현

- DateStep 컴포넌트 구현
  - 숫자만 입력 가능한 날짜 입력 필드 (inputMode="numeric")
  - 자동 yyyy.mm.dd 형식 포맷팅
  - 연도/월/일 유효성 검사 (0으로 시작 방지, 00월/00일 방지 등)
  - 시간대 선택 (점심/저녁) Chip 토글
- useDateStepValidation 훅에 날짜 형식 및 실제 날짜 유효성 검사 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: 날짜 관련 상수 및 유틸 함수 분리

- DATE_PATTERN 상수를 constants/gathering/create로 이동
- formatDateInput, isValidDateFormat 함수를 utils/gathering/create로 이동
- DateStep.tsx, useCreateMeetingForm.ts에서 중복 코드 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: timeSlot 타입을 optional로 변경

- 시간대 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 날짜 입력 필드에 clear 버튼 추가

- showClearButton, onClear prop 활용
- handleDateClear 함수 추가
- handleTimeSlotChange 로직 간소화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refac: 명시적으로 named export

* feat: date-fns를 활용한 날짜 유효성 검사 개선

- date-fns 4.1.0 설치
- isValidDateFormat 함수에서 date-fns의 parse, isValid 사용
- native Date 대신 date-fns로 더 명확한 날짜 검증

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: watch를 useWatch로 변경

- 불필요한 리렌더링 방지를 위해 useWatch 사용
- 지정한 필드만 구독하여 성능 최적화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: isUndefined를 isNil로 변경

- 향후 API 연동 시 null 값 대응을 위해 isNil 사용
- undefined와 null 모두 체크하여 방어적 코드 작성

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: timeSlot 값을 대문자로 변경

- "lunch" | "dinner" → "LUNCH" | "DINNER"
- API 응답값과 일관성 유지를 위한 대문자 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: Prettier 포맷팅 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: hasDateError 로직 개선

- 입력 중 에러 표시 방지 (10자리 완성 시에만 검사)
- DATE_PATTERN 대신 isValidDateFormat 사용으로 실제 날짜 유효성 검사
- useDateStepValidation과 검증 로직 통일

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) UI 구현 (#25)

* fix: location 타입을 optional로 변경

- 장소 선택 해제 시 undefined 허용을 위해 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 Step 3 (장소 선택) 구현

- LocationStep 컴포넌트 구현 (placeholder에서 실제 구현으로)
- 장소 선택 UI 구현 (Chip 활용 - 홍대입구역/강남역)
- 토글 방식 선택 (선택된 항목 다시 클릭 시 해제)
- useLocationStepValidation 훅 활용하여 CTA 활성화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: LocationStep 코드 개선

- Chip 컴포넌트를 LOCATION_OPTIONS 배열로 map 렌더링
- watch를 useWatch로 변경하여 리렌더링 최적화
- location 값을 대문자로 변경 (hongdae → HONGDAE, gangnam → GANGNAM)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 모임 생성 완료 페이지 구현 (#26)

* feat: 모임 생성 완료 페이지 구현

- 완료 페이지 UI 구현 (일러스트레이션, 버튼)
- MeetingCompleteIllustration 컴포넌트 추가 (Figma 시안 기반)
- share util 추가 (Web Share API + 클립보드 fallback)
- 모바일에서만 네이티브 공유 시트 사용 (768px 미만)
- toast success 타입 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: import 경로 수정

* feat: 모임 의견 취합 패널 구성에 필요한 설정 요소 구축 (#27)

* feat: add background prop to Layout components

- Add background prop to Layout.Header
- Add background prop to Layout.Footer
- Add background prop to Layout.Content
- Support "white" | "gray" background variants

* feat: define Opinion step types

- Add OpinionStep union type
- Add OpinionForm interface
- Add FoodCategory and DistanceRange types
- Add RankKey type

* feat: add Opinion base constants

- Add OPINION_STEP_ORDER array
- Add OPINION_TOTAL_STEPS constant
- Add FOOD_CATEGORIES with labels
- Add DISTANCE_OPTIONS

* feat: add rank and UI text constants

- Add RANKS array and RANK_LABELS
- Add NO_CARE_LABEL constant
- Add UI_TEXT object with step-specific texts

* feat: add meeting context and mock data

- Define MeetingContext interface
- Add MOCK_MEETING_DATA for development
- Export meeting-related types

* feat: implement useOpinionForm hook with validation

- Create useOpinionForm with react-hook-form
- Define default values for all form fields
- Add useDistanceStepValidation hook
- Add useDislikeStepValidation hook
- Add usePreferenceStepValidation hook
- Export form type

* feat: implement useOpinionFunnel hook with direction tracking

- Add step state management
- Add direction tracking (forward/backward)
- Implement next/back navigation
- Add isFirstStep/isLastStep helpers

* chore: add clsx dependency and prettier config

- Add clsx package for className utilities
- Add twJoin to prettier tailwindFunctions
- Setup for Opinion component styling

* feat: enhance BackwardButton and StepHeader components

- Add cursor-pointer to BackwardButton
- Add whitespace-pre-line to StepHeader.Description for multiline text
- Remove px-6 from StepHeader.Root (controlled by parent)

* feat: add surface-active color token

- Add --color-surface-active for active state backgrounds
- Used in Opinion feature interactive components

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: clsx 라이브러리 제거 및 조건부 스타일링에 twJoin 함수 적용

* refactor: separate opinion constants into domain modules

도메인별로 constants 를 모듈화하여 관심사 분리
- funnel.ts: Opinion funnel 관련 상수
- distance.ts: Distance 옵션 및 레이블
- food.ts: Food category 옵션 및 레이블
- rank.ts: Rank 관련 상수
- ui-text.ts: UI 텍스트 상수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move MeetingContext type to types module

MeetingContext 타입을 constants 에서 types/gathering 으로 이동
타입은 types 모듈에서 관리하도록 구조 개선

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 백엔드 Enum 명세에 맞춰 클라이언트 내 사용될 Type Literal 값 수정

* feat: 모임 의견 취합 패널 인트로 페이지 구현 (#28)

* feat: add LogoIcon component

- Create LogoIcon SVG component
- Add icon exports

* feat: implement IntroStep component

- Create IntroStep with LogoIcon
- Add meeting date badge
- Use meetingContext for dynamic data
- Add onNext callback prop

* feat: define step component props types

- Add BaseStepProps interface
- Add IntroStepProps type
- Use discriminated union pattern

* feat: create opinion page route with intro step

- Create opinion page.tsx
- Implement intro step rendering
- Add backward navigation to gathering detail
- Use Layout with gray background for intro

* feat: setup opinion component exports

- Create opinion index.ts
- Export IntroStep

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 존재하지 않는 컴포넌트 import 구문을 제거

* fix: Intro 작업에 아직 포함하면 안될 파일들을 일괄 제거

* fix: 상수에서 Type 을 Import 하여 재사용하던 기존의 문제 수정

* fix: 타입 명세 변경에 따라 MeetingContext 를 import 하는 경로 수정

* feat: add opinion-intro illustration to IntroStep

- opinion-intro.svg를 사용하여 일러스트 영역 구현
- Next.js Image 컴포넌트로 SVG 렌더링
- fill 레이아웃 및 object-contain으로 반응형 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: adjust IntroStep header spacing

- h-12 spacer 및 pb-6 제거하여 헤더 영역 간격 조정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: 모임 의견 취합 Step 1 (거리 입력) 구현 (#29)

* feat: implement DistanceStep component

- Add StepIndicator (1/3)
- Add StepHeader with station name
- Add Chip group for distance selection
- Use Controller for form field management
- Add Layout.Footer with 다음 button
- Disable button when no distance selected

* feat: add StepTransition with slide animation

- Use Framer Motion AnimatePresence
- Support forward/backward direction
- Add slide variants with spring physics
- Skip animation for intro step

* feat: add DistanceStepProps export

* fix: Distance 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* feat: 모임 의견 취합 Step 2 (불호 입력) 구현  (#30)

* fix: 인트로 페이지 내 Heading 영역이 중복으로 걸쳐 있던 오류 수정

* feat: add FoodCategoryButton for food categories

- Create 156px circular button
- Add X icon with fade animation on selection
- Support selected/unselected states
- Add hover/active styles

* feat: implement DislikeStep component

- Add StepIndicator (2/3)
- Add StepHeader
- Add FoodCategoryButton grid (3 columns)
- Use Controller for dislikedFoods array
- Add 상관없음 toggle logic
- Add 다음 button (always enabled)

* feat: add Checkbox component for 상관없음

- Create Checkbox with controlled state
- Support checked/unchecked styles
- Add accessibility labels

* feat: add DislikeStepProps export

* fix: Dislike 작업에 아직 포함하면 안될 파일들을 일괄 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: 상관없음 값을 Category 에 종속시킴으로서 발생한 로직 이슈 수정

* feat: 음식 카테고리 버튼 내 일러스트 이미지 추가 및 Image 적용

* fix: clsx 라이브러리를 사용하던 조건부 컴포넌트 제거

* fix: 한 개 이상의 선택지를 채택한 경우 다음 스텝으로 이동하도록 수정

* feat: 모임 의견 취합 Step 3 (선호 음식) 구현  (#31)

* feat: add RankSection component for preference ranking

- Create collapsible rank section (1순위/2순위/3순위)
- Support 상관없음 option per rank
- Handle disabled state when previous rank is none
- Add FoodCategoryButton integration

* feat: implement PreferenceStep component

- Add StepIndicator (3/3)
- Add StepHeader
- Render 3 RankSections
- Use Controller for preferredMenus object
- Implement duplicate detection
- Handle 상관없음 cascade (clear lower ranks)
- Add validation for completion
- Add 완료 button with validation

* feat: add PreferenceStepProps export

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* refactor: optimize PreferenceStep performance

- Extract pure functions (isNoneSelected, isDisabled, isCompleteEnabled) outside component
- Memoize handleMenuSelect with useCallback to prevent unnecessary re-renders
- Use watch() to manage preferredMenus state at component level
- Fix isCompleteEnabled logic to require all ranks when ANY not selected
- Remove isNoneSelected prop from RankSection (derived internally)
- Replace clsx with twJoin for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: 누락되었던 PreferenceStep 등록 절차를 추가하여 적용

* fix: 페이지 단에 Toaster 컴포넌트를 적용하여 토스트 메세지 노출

* feat: 모임 의견 취합 완료 페이지 구축 (#32)

* feat: add CompleteView component

- Create completion message UI
- Add illustration placeholder
- Use gray background
- Add participant count display

* feat: add SubmissionBottomSheet component

- Show submission progress (e.g., 2/5명 제출 완료)
- Add progress bar with percentage
- Add 확인 button
- Navigate to gathering detail on click

* feat: create opinion complete page

- Create complete/page.tsx
- Integrate CompleteView
- Integrate SubmissionBottomSheet
- Use gray background for entire page
- Add mock submission data (2/5)

* feat: prevent horizontal scroll on opinion pages

- Add overflow-x-hidden to html/body
- Add scrollbar-gutter: stable
- Prevent layout shift during animations
- Add Toaster component for notifications

* fix: RankKey 를 잘못된 방향으로 import 했던 구문 수정

* fix: Layout.Root 에 background variant 를 적용했던 구문 제거

* chore: prettier 규격에 맞지 않았던 코드 수정

* fix: pending 으로 의견 수렴 대기 중 페이지 경로를 수정

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* fix: 의견이 다 모이지 않았을 경우 노출되는 텍스트 수정

* feat: 의견 수렴 플로우 및 결과 보기 페이지 구현 (#34)

* feat: add Restaurant and recommendation result types

- Add Restaurant interface for restaurant data
- Add FoodVote interface for vote counting
- Add VoteStatistics interface for opinion statistics
- Add RecommendationResult interface for recommendation data
- Export PendingView, CompleteNotificationView, ResultView
- Remove obsolete Korean comments

* feat: add formatDistance utility function

- Convert meters to human-readable format (m/km)

* feat: add ShareButton component

- Add ShareButton for sharing opinion results
- Use native share API with fallback

* feat: add RestaurantCard component

- Add RestaurantCard with featured and default variants
- Support ranking display with crown icon
- Show rating, distance, and category tags
- Display placeholder for missing images

* feat: add VoteSummarySection component

- Display vote statistics with progress bar
- Show preferred and disliked food categories
- Display vote counts per category

* feat: add PendingView and CompleteNotificationView

- Add PendingView for waiting state when opinions are incomplete
- Add CompleteNotificationView with food carousel animation
- Display appropriate messages based on submission status

* feat: add ResultView component

- Display top recommendation with featured card
- Show vote statistics summary
- List other restaurant candidates
- Integrate RestaurantCard and VoteSummarySection

* feat: add opinion pending and result pages

- Add pending page with guard for complete state
- Add result page with recommendation display
- Add mock recommendation data for testing
- Implement redirect logic based on submission status

* fix: 의견 수렴 대기 중 페이지 내 이미지를 적용

* feat: add FoodCard component for food category display

- Create FoodCard component with 200x180px size
- Display food category images using Next.js Image
- Use fill layout with object-contain for proper image scaling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add FoodCategoryCarousel with infinite scroll animation

- Implement infinite horizontal scroll animation using motion
- Display 6 food categories in repeated loop
- 20-second animation duration with linear easing
- Duplicate categories for seamless infinite effect

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add decorative assets for opinion complete view

- Add chopstick.svg for decorative element
- Add spoon.svg for decorative element
- Assets to be used in opinion complete animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update CompleteView with FoodCategoryCarousel

- Replace static prepare-suggestion image with animated carousel
- Remove totalCount/submittedCount props (no longer needed)
- Simplify to always show completion state
- Integrate FoodCategoryCarousel for dynamic food category display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add opinion complete page

- Create complete page at /gathering/[id]/opinion/complete
- Display CompleteView component
- Show completion state after all opinions submitted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove CompleteNotificationView component

- Delete unused CompleteNotificationView component
- Remove export from index.ts
- Simplify opinion flow by using CompleteView only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update Restaurant and RecommendationResult types to match API response

- Restaurant 인터페이스를 API 응답 구조에 맞게 재정의
  - id → restaurantId (number)
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange (DistanceRange enum)
  - 새로운 필드 추가: rank, address, mapUrl, representativeReview, description, region, location, mediumCategory
- RecommendationResult를 평탄화하여 preferences/dislikes를 Record<string, number>로 직접 포함
- VoteStatistics와 FoodVote 인터페이스 제거 (더 이상 사용하지 않음)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update MOCK_RECOMMENDATION_RESULT with real API data structure

- 실제 API 응답 형식에 맞춰 목 데이터 재구성
- 상세 정보 추가: mapUrl, representativeReview, description, location coordinates
- preferences/dislikes를 Record<string, number> 형식으로 변경
- agreementRate 추가 (50.0%)
- 실제 홍대 음식점 데이터 사용 (또보겠지 떡볶이집, 미분또, 회비어육곱)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: update VoteSummarySection to use new data format

- VoteStatistics 대신 preferences, dislikes, agreementRate를 개별 props로 받도록 변경
- FoodVote[] 배열 대신 Record<string, number> 형식으로 변경
- Object.entries()를 사용하여 Record를 배열로 변환 후 정렬
- submissionRate → agreementRate로 용어 통일

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: update RestaurantCard for new Restaurant model and add mapUrl navigation

- Restaurant 모델 필드명 변경에 맞춰 컴포넌트 업데이트
  - name → restaurantName
  - category → largeCategory
  - distance → majorityDistanceRange
- formatDistance 제거 및 DISTANCE_LABELS 사용으로 변경
- ChevronIcon 클릭 시 mapUrl로 새 창 열기 기능 추가
- handleMapClick 핸들러 추가 (window.open with noopener,noreferrer)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: split RestaurantCard into TopRecommendCard and OtherCandidateCard

- RestaurantCard의 variant 분기를 제거하고 두 개의 별도 컴포넌트로 분리
- TopRecommendCard: 1위 추천 음식점용 (큰 이미지, 왕관 아이콘)
- OtherCandidateCard: 기타 후보용 (작은 이미지, 컴팩트 레이아웃)
- ResultView에서 각각의 전용 컴포넌트 사용
- 불필요한 variant, showRanking props 제거로 props 단순화

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove deprecated CompleteView from exports

- Remove CompleteView export as it will be replaced by CompleteNotificationView

* fix: update SubmissionBottomSheet completion text

- Change completion message to include total count
- Remove leading space from description

* fix: adjust ProgressBar indicator position at 100%

- Fix indicator overflow at 100% completion
- Ensure indicator stays within progress bar bounds

* feat: redirect to pending page after opinion submission

- Change redirect from /complete to /pending
- Allow proper flow through pending -> complete -> result

* refactor: improve layout centering for CompleteView and PendingView

- CompleteView: FoodCategoryCarousel을 flex-1로 수직 중앙 정렬
- PendingView: Image를 flex-1 컨테이너로 감싸서 중앙 정렬, fill 대신 고정 width/height 사용
- index.ts: CompleteView export 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove unused formatDistance utility

- DISTANCE_LABELS로 대체되어 더 이상 사용되지 않음

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify PendingView props and update pending page footer

- PendingView에서 불필요한 props 제거 (gatheringId, totalCount, submittedCount)
- pending 페이지 footer를 ShareButton에서 "추천 결과 보기" Button으로 변경 (disabled 상태)
- ResultView의 VoteSummarySection props 포맷팅 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

* fix: Layout.Footer 내 background 를 white 값으로 수정

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat: 랜딩 페이지 구현 및 OG 메타데이터 추가 (#33)

* feat: OG 메타데이터 추가

- title: 요기잇
- description: 다인원을 위한 맛집 추천 서비스
- og:image placeholder 추가 (추후 이미지 적용 시 활성화)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 구현

- LandingPage 컴포넌트 추가
- Layout.Root 활용하여 일관된 레이아웃 적용
- Figma 디자인 기반 UI 구현:
  - 상단 타이틀 및 로고
  - 음식 일러스트레이션 (초밥, 국밥)
  - 하트 아이콘 장식
  - CTA 버튼 (모임 링크 생성 시작)
- 버튼 클릭 시 /gathering/create 페이지로 라우팅
- 랜딩 페이지 이미지 에셋 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 요소 위치 시안과 동일하게 조정

- 375px 기준 Figma 시안과 동일한 위치로 조정
- 손가락 아이콘 위치를 중앙 하단으로 이동
- 파란색 국밥 카드 회전 각도 15deg 유지
- 하트 아이콘 및 초밥 카드 위치 조정
- 픽셀 값을 Tailwind 스페이싱 유틸리티로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: 랜딩 페이지 위치 미세 조정 및 타이포그래피 유틸리티 추가

- 손가락 아이콘 위치를 Tailwind 스페이싱으로 변환
- 하트 아이콘 위치 미세 조정
- heading-18-bd 타이포그래피 유틸리티 추가
- body-18-bd letter-spacing 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: prettier 포맷 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: 랜딩 페이지 손가락 아이콘 애니메이션 추가

- motion 라이브러리를 활용한 손가락 아이콘 애니메이션 구현
- 초밥 카드를 가리켰다가 국밥 카드로 돌아오는 반복 애니메이션
- 이미지에 priority 속성 추가하여 LCP 최적화
- router.push를 router.replace로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* chore: prettier 포맷에 맞지 않았던 코드 수정

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Gwangin Baik <gwangin1999@naver.com>
github-actions bot pushed a commit that referenced this pull request Feb 16, 2026
## 1.0.0-beta.1 (2026-02-16)

### Features

* [#70](#70) ([#72](#72)) ([b676e0e](b676e0e))
* [QA] 모임 생성 완료, 결과페이지 페이지 UI 개선 ([#66](#66)) ([f10225d](f10225d))
* [QA] 서비스 전체 배경색 및 Layout Root 그림자 효과 적용 ([#59](#59)) ([384b56f](384b56f))
* api client 모듈 생성 ([#37](#37)) ([a37b0a9](a37b0a9)), closes [#38](#38) [#39](#39) [#40](#40) [#41](#41)
* Button 컴포넌트 추가 ([#11](#11)) ([83b7607](83b7607))
* Chip Component 추가 ([#9](#9)) ([e9d8b8f](e9d8b8f))
* Color theme 초기화 ([#2](#2)) ([97f1dcc](97f1dcc))
* DotsLoader 컴포넌트 추가  ([#48](#48)) ([cfe4582](cfe4582)), closes [#49](#49)
* GA4 이벤트 트래킹 통합 ([#70](#70)) ([0c1b9fa](0c1b9fa))
* GTM(Google Tag Manager) 통합을 위한 Analytics 컴포넌트 추가 ([#57](#57)) ([87a6ded](87a6ded))
* IconBase 컴포넌트 및 아이콘 컴포넌트들 구축 ([#13](#13)) ([8557b75](8557b75)), closes [#FFCD00](https://github.com/Nexters/yogieat/issues/FFCD00) [#FFAD00](https://github.com/Nexters/yogieat/issues/FFAD00) [#15](#15) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c)
* InputField 컴포넌트 추가 ([#16](#16)) ([99b8aa2](99b8aa2))
* Landing / Opinion Form 페이지 분리 ([#61](#61)) ([0f11e71](0f11e71))
* Layout 컴포넌트 추가 ([#10](#10)) ([9efce6f](9efce6f))
* Semantic Color Token 추가 ([#19](#19)) ([fcaedaf](fcaedaf))
* Spacing utility 클래스 초기화 ([#8](#8)) ([2e38d7a](2e38d7a))
* Tag 컴포넌트 추가 ([#20](#20)) ([f69dd05](f69dd05))
* Toast 컴포넌트 추가 ([#21](#21)) ([76e84b0](76e84b0))
* 모임 생성 퍼널 Step 1 (인원 선택) 구현 ([#23](#23)) ([7fc01a1](7fc01a1)), closes [#24](#24) [#1f2933](https://github.com/Nexters/yogieat/issues/1f2933) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c) [#25](#25) [#26](#26) [#27](#27) [#28](#28) [#29](#29) [#30](#30) [#31](#31) [#32](#32) [#34](#34)
* 프로젝트 기초 세팅 진행 ([aa0ec20](aa0ec20))
* 프로젝트 폴더 구조 반영 ([e54962d](e54962d))

### Bug Fixes

* 1순위를 1개라도 선택했다면 바로 CTA 가 활성화 되도록 수정 ([#60](#60)) ([e5758b4](e5758b4))
* 1차 MVP 배포 이전 최종 QA 항목 반영 ([#58](#58)) ([6574231](6574231))
* Button/Chip type 속성 추가 및 의견 수렴 UX 개선 ([#50](#50)) ([7e86e4a](7e86e4a)), closes [#51](#51) [#52](#52) [#53](#53) [#54](#54) [#55](#55) [#56](#56)
* cat 에서 echo 로 env.production 파일을 생성하도록 수정 ([f15307d](f15307d))
* CI/CD health check 타이밍 개선 및 수동 배포 기능 추가 ([54fd2b8](54fd2b8))
* Docker build-args로 환경 변수 전달 방식 변경 ([#77](#77)) ([e5fa0b9](e5fa0b9))
* Docker 이미지 강제 pull 및 컨테이너 재생성 ([#79](#79)) ([c253ec1](c253ec1))
* Health check 전략 개선 및 curl 기반으로 변경 ([765d3da](765d3da))
* nginx http2 deprecated 경고 해결 ([2fd9c75](2fd9c75))
* PendingView 내에서 ShareButton 을 렌더링 하지 않도록 수정 ([7bc3e12](7bc3e12))
* 결과 페이지 맛집 이미지 기본 placeholder, 공유하기 toast 미노출 ([#68](#68)) ([3c80844](3c80844))
* 동시 배포 방지를 위한 concurrency 설정 추가 ([e9bfd52](e9bfd52))
* 모임 생성 퍼널 필드 상태 초기화 버그 수정 ([#64](#64)) ([3934066](3934066)), closes [#65](#65)
* 모임 생성 폼 필드명 변경 (meetingDate → scheduledDate, location → region) ([#35](#35)) ([e90beed](e90beed))
* 배포 워크플로우에 GA4 환경 변수 추가 ([#73](#73)) ([835ae1f](835ae1f))
* 의견 수렴 페이지 내 UI 수정 및 인터렉션 개선 ([#36](#36)) ([a74f7da](a74f7da))
* 의견 수합 Form Capacity 폴링 제거 및 ErrorCode 타입 시스템 추가 ([#67](#67)) ([d55dba1](d55dba1))
* 인원 수 선택 Grid 및 의견 수렴 QA 수정 사항 반영 ([f01626e](f01626e))
* 테스트 용으로 추가했던 페이지 제거 및 icons 폴더 추가 ([4116025](4116025))

### Code Refactoring

* Button 컴포넌트 스펙을 Figma 명세에 맞춰 수정 ([#14](#14)) ([2e27f17](2e27f17))

### Build System

* Docker 빌드 시 NEXT_PUBLIC 환경변수 주입 프로세스 추가 ([#47](#47)) ([88ba163](88ba163))

### Documentation

* 프로젝트 개발 가이드 문서 추가 ([#84](#84)) ([4313145](4313145))
github-actions bot pushed a commit that referenced this pull request Feb 16, 2026
## 1.0.0 (2026-02-16)

### Features

* [#70](#70) ([#72](#72)) ([b676e0e](b676e0e))
* [QA] 모임 생성 완료, 결과페이지 페이지 UI 개선 ([#66](#66)) ([f10225d](f10225d))
* [QA] 서비스 전체 배경색 및 Layout Root 그림자 효과 적용 ([#59](#59)) ([384b56f](384b56f))
* analytics 개선 및 네이버 서치 어드바이저 등록 ([#88](#88)) ([4372aa5](4372aa5))
* api client 모듈 생성 ([#37](#37)) ([a37b0a9](a37b0a9)), closes [#38](#38) [#39](#39) [#40](#40) [#41](#41)
* Button 컴포넌트 추가 ([#11](#11)) ([83b7607](83b7607))
* Chip Component 추가 ([#9](#9)) ([e9d8b8f](e9d8b8f))
* Color theme 초기화 ([#2](#2)) ([97f1dcc](97f1dcc))
* DotsLoader 컴포넌트 추가  ([#48](#48)) ([cfe4582](cfe4582)), closes [#49](#49)
* GA4 이벤트 트래킹 통합 ([#70](#70)) ([0c1b9fa](0c1b9fa))
* GTM(Google Tag Manager) 통합을 위한 Analytics 컴포넌트 추가 ([#57](#57)) ([87a6ded](87a6ded))
* IconBase 컴포넌트 및 아이콘 컴포넌트들 구축 ([#13](#13)) ([8557b75](8557b75)), closes [#FFCD00](https://github.com/Nexters/yogieat/issues/FFCD00) [#FFAD00](https://github.com/Nexters/yogieat/issues/FFAD00) [#15](#15) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c)
* InputField 컴포넌트 추가 ([#16](#16)) ([99b8aa2](99b8aa2))
* Landing / Opinion Form 페이지 분리 ([#61](#61)) ([0f11e71](0f11e71))
* Layout 컴포넌트 추가 ([#10](#10)) ([9efce6f](9efce6f))
* Semantic Color Token 추가 ([#19](#19)) ([fcaedaf](fcaedaf))
* Spacing utility 클래스 초기화 ([#8](#8)) ([2e38d7a](2e38d7a))
* Tag 컴포넌트 추가 ([#20](#20)) ([f69dd05](f69dd05))
* Toast 컴포넌트 추가 ([#21](#21)) ([76e84b0](76e84b0))
* 모임 생성 완료 페이지 UI 리뉴얼 ([#89](#89)) ([17a3fc1](17a3fc1))
* 모임 생성 퍼널 Step 1 (인원 선택) 구현 ([#23](#23)) ([7fc01a1](7fc01a1)), closes [#24](#24) [#1f2933](https://github.com/Nexters/yogieat/issues/1f2933) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c) [#25](#25) [#26](#26) [#27](#27) [#28](#28) [#29](#29) [#30](#30) [#31](#31) [#32](#32) [#34](#34)
* 프로젝트 기초 세팅 진행 ([aa0ec20](aa0ec20))
* 프로젝트 폴더 구조 반영 ([e54962d](e54962d))

### Bug Fixes

* 1순위를 1개라도 선택했다면 바로 CTA 가 활성화 되도록 수정 ([#60](#60)) ([e5758b4](e5758b4))
* 1차 MVP 배포 이전 최종 QA 항목 반영 ([#58](#58)) ([6574231](6574231))
* Button/Chip type 속성 추가 및 의견 수렴 UX 개선 ([#50](#50)) ([7e86e4a](7e86e4a)), closes [#51](#51) [#52](#52) [#53](#53) [#54](#54) [#55](#55) [#56](#56)
* cat 에서 echo 로 env.production 파일을 생성하도록 수정 ([f15307d](f15307d))
* CI/CD health check 타이밍 개선 및 수동 배포 기능 추가 ([54fd2b8](54fd2b8))
* Docker build-args로 환경 변수 전달 방식 변경 ([#77](#77)) ([e5fa0b9](e5fa0b9))
* Docker 이미지 강제 pull 및 컨테이너 재생성 ([#79](#79)) ([c253ec1](c253ec1))
* Health check 전략 개선 및 curl 기반으로 변경 ([765d3da](765d3da))
* nginx http2 deprecated 경고 해결 ([2fd9c75](2fd9c75))
* PendingView 내에서 ShareButton 을 렌더링 하지 않도록 수정 ([7bc3e12](7bc3e12))
* 결과 페이지 맛집 이미지 기본 placeholder, 공유하기 toast 미노출 ([#68](#68)) ([3c80844](3c80844))
* 동시 배포 방지를 위한 concurrency 설정 추가 ([e9bfd52](e9bfd52))
* 모임 생성 퍼널 필드 상태 초기화 버그 수정 ([#64](#64)) ([3934066](3934066)), closes [#65](#65)
* 모임 생성 폼 필드명 변경 (meetingDate → scheduledDate, location → region) ([#35](#35)) ([e90beed](e90beed))
* 배포 워크플로우에 GA4 환경 변수 추가 ([#73](#73)) ([835ae1f](835ae1f))
* 의견 수렴 페이지 내 UI 수정 및 인터렉션 개선 ([#36](#36)) ([a74f7da](a74f7da))
* 의견 수합 Form Capacity 폴링 제거 및 ErrorCode 타입 시스템 추가 ([#67](#67)) ([d55dba1](d55dba1))
* 인원 수 선택 Grid 및 의견 수렴 QA 수정 사항 반영 ([f01626e](f01626e))
* 테스트 용으로 추가했던 페이지 제거 및 icons 폴더 추가 ([4116025](4116025))

### Code Refactoring

* Button 컴포넌트 스펙을 Figma 명세에 맞춰 수정 ([#14](#14)) ([2e27f17](2e27f17))

### Build System

* Docker 빌드 시 NEXT_PUBLIC 환경변수 주입 프로세스 추가 ([#47](#47)) ([88ba163](88ba163))

### Documentation

* 프로젝트 개발 가이드 문서 추가 ([#84](#84)) ([4313145](4313145))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants