Skip to content

refactor: 하단 탭 네비게이션 개편 (4탭 + 글래스) - #354

Merged
iOdiO89 merged 28 commits into
devfrom
refactor/340-bottom-tab
Jul 19, 2026
Merged

refactor: 하단 탭 네비게이션 개편 (4탭 + 글래스)#354
iOdiO89 merged 28 commits into
devfrom
refactor/340-bottom-tab

Conversation

@iOdiO89

@iOdiO89 iOdiO89 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

작업 요약

  • 바텀탭을 4개 탭(홈·위시·토너먼트·마이)으로 개편하고 마이페이지에도 노출합니다
  • 인디케이터를 꾹 잡고 드래그하거나 탭해서 이동하는 liquid glass 인터랙션을 추가합니다
  • 헤더의 프로필 아이콘을 제거하고 마이 탭으로 진입 동선을 일원화합니다
  • 바텀탭 z-index를 Z_INDEX 상수로 통일합니다

작업 세부 내용

바텀탭 개편

  • 기존 2개 탭(홈·보관)을 홈 / 위시 / 토너먼트 / 마이 4개 탭으로 분리
  • 각 탭에 active/inactive 아이콘(fill/outline)을 분리 적용, home outline 아이콘 신규 추가
  • buttonnext/link<Link>로 교체해 마크업을 시맨틱하게 정리
  • 마이페이지(/mypage)에도 바텀탭을 노출하고, 겹침 방지를 위해 pbpb-32로 조정

Liquid glass 인터랙션

  • 활성 탭 인디케이터를 드래그로 옮기거나 탭해서 이동 가능하도록 포인터 제스처 구현
    • DRAG_THRESHOLD(12px) 이상 이동 시에만 드래그로 판정해 손떨림 탭 오작동 방지
    • 포커스되지 않은 탭을 눌러도 버블이 미끄러져 와 드래그를 이어받도록 처리
  • 프레스 시 유리 렌즈로 변신 → 이동/스냅 후 무광 알약으로 복귀하는 상태 전환 분리
    • 이동 속도 기반 스쿼시/스큐, 반사광 잔상 등 물리 기반 모션 추가
    • 스프링 오버슈트 / 슬라이드 이징을 거리에 따라 구분 적용
  • 릴리즈 후 착지 애니메이션(NAVIGATE_DELAY 380ms)을 마친 뒤 라우팅 처리하고, 제스처로 처리된 Link 클릭은 onClickCapture에서 차단

헤더 / 기타

  • 홈·아카이브 헤더의 PROFILE 아이콘 제거 (마이 탭 신설로 동선 일원화)
  • 바텀탭 관련 하드코딩 z-20Z_INDEX.BOTTOM_TAB_BAR 상수로 교체
  • next.config.mjs의 SVGR 설정에서 removeViewBox: false 적용 — 아이콘 축소 렌더링 시 잘림 방지

스크린샷

2026-07-18.12.59.56.mov
2026-07-18.12.47.53.mov

연관 이슈

closes #340

Summary by CodeRabbit

  • 새로운 기능
    • 홈/위시리스트/토너먼트/마이로 이동하는 4탭 하단 내비게이션(드래그 기반 전환) 추가.
  • 개선
    • 여러 화면에서 하단 CTA·탭바 배치/여백을 조정해 겹침을 줄임.
    • 앱 스플래시 오버레이 표시 방식 개선, 공유 바텀시트 오류 아이콘 교체.
    • 로그인 진입 시 세션 상태에 따라 멤버는 홈으로 자동 이동.
  • 테스트/기타
    • 웹 E2E 테스트 및 CI 실행을 보강.

@iOdiO89 iOdiO89 self-assigned this Jul 17, 2026
@iOdiO89 iOdiO89 linked an issue Jul 17, 2026 that may be closed by this pull request
5 tasks
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
piki Ready Ready Preview, Comment Jul 19, 2026 5:52am

@github-actions github-actions Bot added the refactor Extra attention is needed label Jul 17, 2026
@github-actions
github-actions Bot requested review from soyeong0115 and ychany July 17, 2026 16:01
@github-actions

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3023450d-fb17-4a2d-8b3f-658b30fbf758

📥 Commits

Reviewing files that changed from the base of the PR and between b847c93 and 7646b69.

⛔ Files ignored due to path filters (4)
  • apps/app/assets/images/share-bottom-sheet/icon-error.png is excluded by !**/*.png
  • apps/app/assets/images/splash-android-blank.png is excluded by !**/*.png
  • apps/web/src/assets/fonts/PretendardVariable.woff2 is excluded by !**/*.woff2
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (45)
  • .github/workflows/ci.yml
  • .gitignore
  • CLAUDE.md
  • apps/app/.gitignore
  • apps/app/app.json
  • apps/app/app/index.tsx
  • apps/app/components/ShareBottomSheet.tsx
  • apps/app/components/SplashOverlay.tsx
  • apps/app/hooks/useSplashScreenController.tsx
  • apps/app/package.json
  • apps/web/e2e/README.md
  • apps/web/e2e/consts.ts
  • apps/web/e2e/fixtures/mockApiFixture.ts
  • apps/web/e2e/helpers/apiResponse.ts
  • apps/web/e2e/helpers/fakeJwt.ts
  • apps/web/e2e/mocks/images.ts
  • apps/web/e2e/mocks/me.ts
  • apps/web/e2e/mocks/tournament.ts
  • apps/web/e2e/setup/auth.setup.ts
  • apps/web/e2e/setup/globalSetup.ts
  • apps/web/e2e/setup/mockApiServer.ts
  • apps/web/e2e/specs/home/home.spec.ts
  • apps/web/e2e/specs/tournament/tournamentCreate.spec.ts
  • apps/web/package.json
  • apps/web/playwright.config.ts
  • apps/web/src/app/_components/SplashClient.tsx
  • apps/web/src/app/_components/splash.css
  • apps/web/src/app/archive/wish/[id]/_components/ItemEditForm.tsx
  • apps/web/src/app/archive/wish/_hooks/useShareIntentWish.ts
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/login/_components/LoginButtons.tsx
  • apps/web/src/app/login/layout.tsx
  • apps/web/src/app/login/page.tsx
  • apps/web/src/app/mypage/edit/_components/EditForm.tsx
  • apps/web/src/app/mypage/withdraw/_components/WithdrawConfirmDialog.tsx
  • apps/web/src/app/tournament/[id]/create/by-wish/_components/ByWishContent.tsx
  • apps/web/src/app/tournament/[id]/item/[itemId]/_components/ItemEditForm.tsx
  • apps/web/src/app/tournament/[id]/result/_components/ResultClient.tsx
  • apps/web/src/components/Providers.tsx
  • apps/web/src/components/bottom-cta/index.tsx
  • apps/web/src/styles/globals.css
  • apps/web/src/utils/auth.ts
  • apps/web/tsconfig.json
  • package.json
  • prettier.config.mjs

📝 Walkthrough

Walkthrough

4탭 글래스형 BottomTabBar와 드래그·스냅 라우팅, Playwright E2E 환경, 앱 스플래시 오버레이, 로그인·공통 CTA·웹 레이아웃 변경이 추가되었습니다. SVG 변환 시 viewBox 보존 설정도 적용되었습니다.

Changes

웹 네비게이션 및 공통 UI

Layer / File(s) Summary
드래그형 BottomTabBar 구현
apps/web/src/components/bottom-tab-bar/index.tsx, apps/web/src/assets/icons/outline/index.ts
홈·위시·토너먼트·마이 탭과 포인터 드래그·스냅·지연 라우팅 및 글래스 인디케이터를 구현했습니다.
페이지별 탭 바 배치
apps/web/src/app/home/page.tsx, apps/web/src/app/archive/tournament/..., apps/web/src/app/mypage/page.tsx
페이지별 BottomTabBar 위치와 하단 여백을 조정했습니다.
공통 CTA 스타일 통합
apps/web/src/components/bottom-cta/index.tsx, apps/web/src/app/tournament/..., apps/web/src/app/mypage/..., apps/web/src/app/archive/...
BottomCta에 그라디언트 처리를 추가하고 기존 CTA 래퍼 스타일을 공통 컴포넌트로 통합했습니다.

Playwright E2E 환경

Layer / File(s) Summary
목 데이터와 요청 처리
apps/web/e2e/mocks/*, apps/web/e2e/helpers/*, apps/web/e2e/fixtures/*, apps/web/e2e/setup/*
브라우저·SSR API 목킹, 게스트 인증, 이미지·SSE 처리와 누락 요청 검증을 추가했습니다.
실행 설정과 CI 통합
apps/web/playwright.config.ts, apps/web/package.json, .github/workflows/ci.yml, apps/web/e2e/specs/*
Playwright 프로젝트·스크립트·샘플 테스트와 CI 실행 및 실패 산출물 업로드를 구성했습니다.

앱 스플래시 및 웹 인증

Layer / File(s) Summary
앱 스플래시 오버레이
apps/app/hooks/useSplashScreenController.tsx, apps/app/components/SplashOverlay.tsx, apps/app/app/index.tsx, apps/app/app.json
네이티브 스플래시를 숨긴 뒤 WebView 준비 전 React Native 오버레이를 표시하도록 변경했습니다.
로그인 및 웹 런타임
apps/web/src/app/login/*, apps/web/src/utils/auth.ts, apps/web/src/app/layout.tsx, apps/web/src/components/Providers.tsx
토큰 역할 판별과 멤버 리디렉션을 추가하고, 게스트 로그인·폰트·Devtools·스플래시 렌더링을 변경했습니다.

SVG 처리 설정

Layer / File(s) Summary
SVGO viewBox 보존 설정
apps/web/next.config.mjs
SVGR 로더에 SVGO preset-defaultremoveViewBox: false를 적용했습니다.

Estimated code review effort: 5 (Critical) | ~90 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant BottomTabBar
  participant Router
  User->>BottomTabBar: 포인터 입력 및 드래그
  BottomTabBar->>BottomTabBar: 인디케이터 스냅
  BottomTabBar->>Router: 지연된 router.push 호출
Loading

Possibly related issues

Possibly related PRs

  • TeamPiKi/client#319: Playwright 설정·목 서버·fixture·CI E2E 잡이 동일한 코드 영역과 연결됩니다.
  • TeamPiKi/client#345: BottomCta 그라디언트와 여러 사용부 변경이 동일한 컴포넌트 흐름과 겹칩니다.
  • TeamPiKi/client#348: 로그인, 스플래시, 폰트와 Devtools 변경이 동일한 웹 코드 경로를 다룹니다.

Suggested labels: refactor

Suggested reviewers: soyeong0115, ychany

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 4탭 바텀 네비게이션과 글래스 개편이라는 핵심 변경을 간결하게 요약합니다.
Linked Issues check ✅ Passed 4탭 전환, 마이 탭 추가, 프로필 아이콘 제거, 글래스 효과, 활성 상태 갱신이 모두 반영된 것으로 보입니다.
Out of Scope Changes check ✅ Passed 수정된 파일들이 바텀탭 개편과 관련된 범위에 머물러 보이며 뚜렷한 무관 변경은 없습니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/340-bottom-tab

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.3)
apps/app/app.json

File contains syntax errors that prevent linting: Line 21: Expected a property but instead found '// NOTE: 배포할때 'production'으로 변경'.; Line 22: expected , but instead found "com.apple.security.application-groups"


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
apps/web/src/components/bottom-tab-bar/index.tsx (1)

43-49: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

고정된 320px 탭 바를 반응형 너비로 변경하세요.

탭 너비와 위치 계산이 픽셀 상수에 결합되어 좁은 화면이나 확대 환경에서 탭 바가 넘칠 수 있습니다. 컨테이너는 w-full px-5 max-w-*, 탭은 가변 너비를 사용하고 실제 측정 너비로 인디케이터 위치를 계산하는 편이 안전합니다.

As per coding guidelines, “Avoid fixed widths; use the mobile-friendly w-full px-5 pattern with max-w-* for upper bounds.”

Also applies to: 68-71, 290-300

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/bottom-tab-bar/index.tsx` around lines 43 - 49,
Replace the fixed pixel sizing in the bottom tab bar, including TAB_WIDTH,
TAB_GAP, BAR_PADDING, TAB_STEP, and BAR_WIDTH, with a responsive w-full px-5
container and an appropriate max-w-* upper bound. Make tabs flexibly fill the
available width, and calculate the indicator position from the rendered
tab/container measurements rather than hardcoded constants, including the
related logic around the tab layout and indicator positioning.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/components/bottom-tab-bar/index.tsx`:
- Around line 161-168: Separate pointercancel handling from handleUp so
cancellation never triggers snap or routing. Add a cancel-specific handler that
removes the gesture listeners, clears the grabbing/pressed visual state, and
restores the indicator to the active tab; keep handleUp responsible only for
completed gestures and navigation, and register the cancel handler for
pointercancel.
- Around line 52-53: Update NAVIGATE_DELAY and the related navigation timing at
the drag-snap and tab-slide transition handlers so routing occurs only after the
full landing animation completes. Either reduce each transition’s total duration
to 380ms or less, or increase NAVIGATE_DELAY to match the longest transition,
including its animation and delay.
- Around line 99-115: Update the new-gesture initialization in handlePointerDown
and the corresponding path around the referenced later lines to cancel any
pending navigation timer before starting another tab interaction. Clear
navigateTimerRef.current and reset it appropriately so an older delayed
router.push cannot run after a newer selection begins.

---

Nitpick comments:
In `@apps/web/src/components/bottom-tab-bar/index.tsx`:
- Around line 43-49: Replace the fixed pixel sizing in the bottom tab bar,
including TAB_WIDTH, TAB_GAP, BAR_PADDING, TAB_STEP, and BAR_WIDTH, with a
responsive w-full px-5 container and an appropriate max-w-* upper bound. Make
tabs flexibly fill the available width, and calculate the indicator position
from the rendered tab/container measurements rather than hardcoded constants,
including the related logic around the tab layout and indicator positioning.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d20ed86b-493c-4304-94a7-24dd6883cd14

📥 Commits

Reviewing files that changed from the base of the PR and between 31eda14 and d074ef6.

⛔ Files ignored due to path filters (1)
  • apps/web/src/assets/icons/outline/home.svg is excluded by !**/*.svg
📒 Files selected for processing (10)
  • apps/web/next.config.mjs
  • apps/web/src/app/archive/_common/_components/ArchivePageLayout.tsx
  • apps/web/src/app/archive/tournament/_components/ArchiveTournamentClient.tsx
  • apps/web/src/app/archive/tournament/page.tsx
  • apps/web/src/app/archive/wish/_components/WishlistBottomBar.tsx
  • apps/web/src/app/home/page.tsx
  • apps/web/src/app/mypage/page.tsx
  • apps/web/src/assets/icons/outline/index.ts
  • apps/web/src/components/bottom-tab-bar/index.tsx
  • apps/web/src/consts/zIndex.ts
💤 Files with no reviewable changes (1)
  • apps/web/src/app/archive/tournament/_components/ArchiveTournamentClient.tsx

Comment thread apps/web/src/components/bottom-tab-bar/index.tsx Outdated
Comment thread apps/web/src/components/bottom-tab-bar/index.tsx
Comment thread apps/web/src/components/bottom-tab-bar/index.tsx Outdated
iOdiO89 and others added 4 commits July 19, 2026 14:50
* refactor: access token JWT에서 role 추출하는 유틸 추가

* refactor: 로그인 세션 검사(getMe) 제거하고 JWT role 기반으로 전환

* refactor: 게스트 세션 재활용 판정을 클릭 시점 refresh로 일원화

* fix: 루트 스플래시 배경 FOUC 제거

* feat: 로그인 진입 시 문구·버튼 fade-in 애니메이션 추가

* refactor: /archive 탭을 위시리스트·내 토너먼트 페이지로 분리 (#347)

* refactor: /archive 탭 쿼리 파라미터를 /archive/wish, /archive/tournament 경로로 분리

* refactor: 구버전 /archive(?tab=) 경로를 신규 경로로 리다이렉트

* refactor: 옛 /wish 페이지 잔재 정리 및 archive 콜로케이션 재배치

* fix: 위시 페이지 체류 중 후속 공유 인텐트가 무시되던 문제 수정

* fix: 보관 탭 활성 판정 경로 경계 추가 및 위시 추가 후 중복 라우팅 제거

* fix: 공유 인텐트 실패 URL 잠금 해제 및 링크 담기 실패 시 다이얼로그 유지

* refactor: JWT role을 명시적 검증으로 좁혀 타입 단언 제거

* fix: share intent 처리 후 URL 잠금 해제하여 재공유 허용

* refactor: font preload 삭제

* refactor: Pretendard 폰트 CDN Dynamic Subset Variable로 교체

* chore: TanstackQuery devtool Dynamic Import로 변경

* chore: Tanstack Query Devtools ssr false 설정
ychany and others added 8 commits July 19, 2026 14:50
* fix: 카카오 로그인 안드로이드 리다이렉트 수신 액티비티 등록

* chore: 서명 자격증명 및 빌드 산출물 gitignore 추가
* fix: Android 12+ 스플래시 로고 저해상도 문제 해결 (RN 오버레이로 전환)

* fix: Android 시스템 스플래시 저품질 로고 미노출 처리 (배경색만 표시)

* fix: SplashScreen.hideAsync rejection 처리 추가
* feat: 바텀 CTA 상단 그라데이션 옵션 추가 및 패딩 스펙 반영

* refactor: 페이지별 바텀 CTA를 BottomCta 공통 컴포넌트로 교체
* chore: iOS 앱 공유 바텀 시트 에셋 추가

* feat: iOS 앱 공유 바텀시트 성공/에러 UI 추가
* chore: playwright 설치

* chore: Playwright 설정 및 테스트 스크립트 추가

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

* feat: 게스트 storageState 생성 setup 추가

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

* feat: page.route 기반 API 목킹 fixture 및 목 데이터 추가

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

* test: 홈 및 토너먼트 준비 페이지 E2E 테스트 추가

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

* fix: SSR 접근 권한 조회용 목 스텁 서버 추가 및 준비 페이지 테스트를 진입 플로우로 변경

* chore: playwright/.auth gitignore 패턴 수정

* chore: E2E 테스트 CI 잡 추가

* fix: UI 모드와 CLI 동시 실행 시 목 스텁 포트 충돌 해결

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

* fix: dev 전용 react-grab 스크립트 차단으로 trace 스냅샷 빈 화면 해결

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

* chore: CI Node 버전 22 LTS로 변경

* refactor: E2E 테스트를 도메인 폴더 구조로 변경

* refactor: @e2e alias 도입

* feat: E2E 이미지 목킹 추가 (가짜 CDN URL + /_next/image 인터셉트)

* feat: api 목킹 fixture에 patch, delete 메서드 추가

* docs: E2E 테스트 사용 가이드 추가

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Jung Sun A <amber0809@naver.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: 하단 탭 네비게이션 개편 (4탭 + 글래스)

3 participants