feat: 모바일 UX 개편 + 공지사항/검색 기능 + 보안 폴리싱#30
Merged
Merged
Conversation
- seed: 평문 자격증명 제거, env(SEED_ADMIN_*) 로 분리
(운영에선 미설정 시 즉시 실패)
- web: 401 응답 시 authStore 정리 + /admin/login 으로 리다이렉트
→ 좀비 세션(DB 재시드, secret 교체 등) 자동 복구
Zone enum 에 UICHEON 추가하고 모든 라벨 매핑/select 옵션 업데이트. 마이그레이션은 ALTER TYPE ... ADD VALUE 단순 추가라 다운타임 없음.
상단 필터바(ZoneTabs + FilterChips) 제거하고 우측 하단 FAB 묶음에 필터 버튼 추가. 탭하면 구역/영업/카테고리/예산을 한 시트에서 통합 관리. 현재 위치/검색과 동일한 44x44 원형 스타일, 활성 필터는 카운트 배지로 표시. 기존 ZoneTabs.tsx, FilterChips.tsx 는 page.tsx 에서 import 만 끊고 파일은 보존 (트리쉐이킹으로 번들 미포함).
상단 헤더를 투명 floating 으로 바꾸고 로고/메뉴를 각각 frosted glass pill 로 분리. 지도가 헤더 영역까지 채워져 immersive 한 모바일 UX 완성. - MobileHeader: position fixed, 배경 투명, 로고/메뉴 각각 pill (bg-surface/85 + backdrop-blur-md + shadow-md, h-11) - 상단 padding: max(safe-area-inset-top, 0.75rem) 로 비노치 디바이스에서도 최소 12px 여백 보장 - themeColor: #D85A30 → #FAF7F2 (canvas) — iOS Safari URL바/PWA 상태바 색이 새 디자인과 어울리도록 - overscroll-behavior-y: none — 지도 위 pull-to-refresh 차단 (지도 줌/팬 중 의도치 않은 새로고침 방지)
관리자가 작성하고 일반 사용자가 읽는 단방향 공지 시스템.
헤더 메뉴에서 진입, 카테고리 필터/고정/미확인 배지 지원.
- DB: Notice 모델 + NoticeCategory enum (공지/업데이트/이벤트)
+ Admin 작성자 관계
- API: /notices CRUD (목록/상세 공개, 작성/수정/삭제 Admin)
고정글 우선 + publishedAt desc 정렬, category 필터
- Web 공개: /notice 목록 + /notice/[id] 상세
마크다운 본문은 whitespace-pre-wrap 으로 줄바꿈 보존 (MVP)
- Web 관리: /admin/notices CRUD, 사이드바 메뉴 추가
- 미확인 배지: localStorage 의 lastSeenNoticeAt 기준 카운트,
메뉴 햄버거 빨간 점 + 드롭다운 안 카운트 숫자
기존 검색 FAB 가 BottomSheet 를 full 로 펼치기만 하던 것을, 풀스크린 검색 시트로 연결. 입력에 따라 식당 이름을 실시간으로 필터링하고 결과 탭 시 식당 상세 페이지로 이동. - SearchSheet: 풀스크린 모달, 입력 자동 포커스, X 로 닫기 - 클라이언트 사이드 substring 매칭 (대소문자 무시) - 메인 화면 필터와 무관하게 전체 식당 대상 검색 - 결과 0건/입력 전/로딩 중 빈 상태 메시지 분리
구역/카테고리를 단일 선택에서 배열 토글로 확장. 다중 선택 모드에서
어색해진 전체칩을 제거하고, 섹션 헤더의 (N) 카운트 + 초기화
링크 패턴으로 대체.
- API: QueryRestaurantDto 의 zones[]/categoryIds[] 다중 지원
(Prisma in 연산자, Transform 으로 단일/배열 둘 다 수용)
- 공통 타입/프론트 store: zones/categoryIds 배열 + toggle/clear
- FilterSheet: SectionHeader 컴포넌트 도입 — 활성 시 (N) 카운트
+ 우측 초기화 링크 노출
- FilterButton: 카운트 = 활성 항목 합계
- 미사용 단일 선택 잔재 FilterChips, ZoneTabs 파일 삭제
선택된 필터(구역/카테고리/영업/예산)를 BottomSheet 콘텐츠 최상단에 chip 형태로 노출. 각 chip 의 X 탭으로 즉시 해당 필터 제거. 지도 영역 위에 floating 으로 띄우는 안(A)도 검토했으나, 직전에 완성한 immersive 헤더 디자인을 깎지 않으면서 결과와 시각적으로 묶이는 BottomSheet 통합(B)으로 결정. - ActiveFilterBar 컴포넌트 신규 (variant: 'floating'|'inline') - 모바일 BottomSheet + 데스크톱 사이드바 둘 다 inline 으로 통합 - 활성 필터 0건일 때 컴포넌트 자체가 null → 공간 차지 0
기존엔 결과 0건이면 무조건 아직 등록된 식당이 없어요가 떴는데, DB에 식당이 있고 단지 필터가 안 맞는 케이스에선 메시지가 거짓처럼 들렸다. 사용자가 활성 필터 5개 보면서 등록 자체가 없다는 메시지를 보면 혼란. - 필터 활성 + 결과 0: 이 조건에 맞는 식당이 없어요 + 안내 카피 + 필터 전체 초기화 버튼 (RotateCcw 아이콘) - 필터 없음 + 결과 0: 기존 아직 등록된 식당이 없어요 유지 - useFilterStore 의 reset() 으로 한 번에 모든 필터 비움 → 사용자가 막다른 길에서 한 탭으로 회복
- web .eslintrc.js: root config 의 extend 제거. 모노레포에서 next/core-web-vitals 와 root 가 둘 다 import 플러그인을 등록해 pnpm 호이스팅으로 다른 인스턴스로 잡혀 충돌하던 문제 해결. 필요한 룰 (@typescript-eslint, import/order 등) 은 web 자체 config 에 직접 명시. - page.tsx: import 순서 수정 (SearchSheet → BottomSheetContent 뒤) - FilterButton.tsx: 다중선택 리팩토링 후 미사용으로 남은 useCategories, ZONE_LABEL import 제거
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
주요 변경 사항은 모바일 UX 전면 개편, 공지사항/검색 신규 기능, 그리고
관리자 인증·운영 보안 개선 입니다.
주요 변경
🔒 보안 / 운영 안정성
SEED_ADMIN_*). 운영에서 미설정 시즉시 실패하도록 가드
대응)
🗺 메인 화면 UX 전면 개편
패턴으로 통합. 지도 가시 영역 ~96px 회수
pill 로 분리
🔍 필터 기능 확장
(N)카운트 + "초기화" 링크."전체"/"제한 없음" 칩 제거
📢 공지사항 게시판 (신규 기능)
Notice모델 +NoticeCategoryenum (공지/업데이트/이벤트)/noticesCRUD (목록/상세 공개, 작성/수정/삭제 Admin)/notice목록 +/notice/[id]상세/admin/noticesCRUD + 사이드바 메뉴lastSeenNoticeAt기준📱 모바일 디테일 폴리싱
themeColor#D85A30→#FAF7F2(Safari URL바 톤을 새 디자인과 일관)overscroll-behavior-y: none— 지도 위 pull-to-refresh 차단max(safe-area, 0.75rem)— 비노치 디바이스 최소 여백🗄 DB 마이그레이션 (배포 전 실행 필수)
PR 머지 후 운영 환경에서:
```bash
./scripts/migrate-prod.sh deploy
```
추가되는 마이그레이션 2건:
20260507025053_add_uicheon_zone— Zone enum 에UICHEON값 추가20260507052428_add_notice—Notice테이블 +NoticeCategoryenum둘 다
ALTER TYPE ... ADD VALUE/CREATE TABLE으로 다운타임 없음.⚙️ 환경변수 신규
운영 EC2 의
.env.production에 추가:```
SEED_ADMIN_EMAIL=admin@pangchelin.app
SEED_ADMIN_PASSWORD=<강력 비밀번호>
```
(시드 재실행 안 할 거면 생략 가능. 시드는 1회성)
✂️ 삭제된 파일 — 의도된 정리
docs/KNOWN_ISSUES.md— 작성자 결정으로 삭제apps/web/components/filters/FilterChips.tsx,ZoneTabs.tsx—단일 선택 시절 잔재, 새 디자인 도입 후 import 0
.env.production.dgx.example,docs/배포_DGX.md,scripts/{deploy,backup}-dgx.sh)Test plan
메인 화면
검색
공지
보안
모바일 (실기기 권장)