Skip to content

feat: 모임 생성 완료 페이지 구현#26

Merged
RookieAND merged 6 commits intofeature/gathering-create-step3from
feature/gathering-create-complete
Jan 27, 2026
Merged

feat: 모임 생성 완료 페이지 구현#26
RookieAND merged 6 commits intofeature/gathering-create-step3from
feature/gathering-create-complete

Conversation

@youngminss
Copy link
Copy Markdown
Member

@youngminss youngminss commented Jan 24, 2026

🎯 PR 제목

모임 생성 완료 페이지 구현

📑 작업 상세 내역

완료 페이지 UI

  • /gathering/create/complete 페이지 라우트 생성
  • 제목: "모임 준비 끝! 공유하고 맛집을 정해보세요"
  • 하단 버튼: "내 취향 입력" (tertiary), "링크 공유" (secondary)

MeetingCompleteIllustration 컴포넌트

  • Figma 시안 기반 SVG 일러스트 구현
  • 캘린더 카드 + 그릇/젓가락/숟가락 디자인

share util (src/utils/share.ts)

  • 재사용 가능한 공유 유틸 함수 분리
  • 모바일 (768px 미만): 네이티브 공유 시트 (Web Share API)
  • 데스크톱: 클립보드 복사 + toast 알림
  • 데스크톱에서 Web Share API의 popover UX가 좋지 않아 클립보드 복사로 대체

toast 확장

  • toast.success 타입 추가 (클립보드 복사 성공 알림용)

🙏 리뷰 요청 사항

  • 일러스트 SVG가 Figma 시안과 일치하는지 확인 부탁드립니다
  • share util의 모바일 breakpoint(768px) 기준이 적절한지 의견 부탁드립니다

📃 참고 자료

  • Figma: node-id=219-1357

🖼️ 작업 결과물

완료 페이지
/gathering/create/complete

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@youngminss youngminss self-assigned this Jan 24, 2026
@github-actions github-actions bot requested a review from RookieAND January 24, 2026 17:50
@github-actions github-actions bot added ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 ✨ Feature 기능 개발 labels Jan 24, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @youngminss, 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은 모임 생성 완료 페이지를 도입하여 사용자가 모임을 성공적으로 만든 후 사용자 친화적인 인터페이스를 제공합니다. 새로운 일러스트레이션과 모임 링크를 공유하는 기능이 포함되어 있으며, 모바일에서는 네이티브 Web Share API를 활용하고 다른 기기에서는 클립보드 복사로 대체하며 적절한 토스트 알림을 제공합니다.

Highlights

  • 새로운 페이지 구현: 모임 생성 완료 페이지 UI가 구현되었습니다. 이 페이지는 모임 생성 후 사용자에게 완료를 알리고 다음 단계를 안내합니다.
  • 일러스트레이션 컴포넌트 추가: Figma 시안을 기반으로 한 MeetingCompleteIllustration 컴포넌트가 추가되어 완료 페이지의 시각적 요소를 제공합니다.
  • 공유 유틸리티 구현: Web Share API를 활용하고 클립보드 복사 기능을 폴백으로 사용하는 share 유틸리티가 추가되었습니다. 모바일 환경에서는 네이티브 공유 시트를 사용합니다.
  • 토스트 메시지 타입 확장: 토스트 메시지에 success 타입이 추가되어 성공적인 작업 완료를 사용자에게 시각적으로 알릴 수 있게 되었습니다.

🧠 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.

@github-actions github-actions bot added ✨ Feature 기능 개발 and removed ✨ Feature 기능 개발 ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 labels Jan 24, 2026
Copy link
Copy Markdown
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

모임 생성 완료 페이지와 관련 기능 추가에 대한 코드 리뷰입니다. 전반적으로 기능 구현은 잘 되었으나, 몇 가지 스타일 가이드 위반 사항과 개선점이 발견되었습니다.
주요 피드백은 다음과 같습니다:

  • 컴포넌트 작성 방식, import 경로, 타이포그래피 및 간격 토큰 사용 등 다수의 스타일 가이드 규칙 위반 사항을 수정해야 합니다.
  • SVG 일러스트레이션에 하드코딩된 색상 값을 디자인 토큰으로 교체해야 합니다.
  • share 유틸리티에서 Web Share API 사용 방식이 비효율적이므로 개선이 필요합니다.
  • toast 유틸리티에 추가된 스타일에도 하드코딩된 값이 포함되어 있습니다.
    자세한 내용은 각 파일의 인라인 코멘트를 참고해주세요.

Comment on lines +42 to +45
const text = [data.title, data.text, data.url]
.filter(Boolean)
.join("\n");
await navigator.share({ text });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Web Share API는 title, text, url 속성을 개별적으로 전달받을 수 있습니다. 현재 모든 정보를 하나의 text 문자열로 합쳐서 전달하고 있는데, 이는 각 플랫폼의 네이티브 공유 UI에서 최적의 경험을 제공하지 못할 수 있습니다. navigator.sharedata 객체의 속성들을 그대로 전달하도록 수정해주세요.

			await navigator.share({ title: data.title, text: data.text, url: data.url });

@youngminss youngminss added the ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 label Jan 24, 2026
@github-actions github-actions bot added ✨ Feature 기능 개발 and removed ✨ Feature 기능 개발 ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 labels Jan 24, 2026
@youngminss youngminss added the ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 label Jan 24, 2026
Comment on lines +10 to +13
success: (message: string, options?: ToastOptions) => {
sonnerToast(message, {
classNames: {
toast: "ygi:bg-button-primary! ygi:text-text-inverse! ygi:body-14-md! ygi:rounded-sm! ygi:py-3! ygi:px-5! ygi:flex! ygi:items-center! ygi:justify-center! ygi:border-none!",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

오 궁금한 게 여기 ! 으로 important 처리를 한 이유가 있을까? 크게 오버라이딩을 해야 할 상황이 있었는지도 궁금하네.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sonner 라이브러리가 자체 기본 스타일을 가지고 있어서, CSS specificity 문제로 커스텀 스타일이 sonner 기본 스타일에 덮어씌워졌어, !important로 오버라이드해서 디자인 시스템 스타일 적용을 보장하기 위해 사용했어 !

youngminss and others added 4 commits January 27, 2026 00:20
* 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 메타데이터 추가

- 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>
@RookieAND RookieAND merged commit 6e7621e into feature/gathering-create-step3 Jan 27, 2026
6 checks passed
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