Skip to content

Repository files navigation

MoveMate (Frontend)

이사 일정·행정 절차·맞춤 정책을 한 곳에서 관리하는 대시보드. 다크 테마 + 오렌지 포인트 컬러 (Figma 목업 기반).

Stack

  • Next.js 15 (App Router) / React 19 / TypeScript
  • Tailwind CSS v4 — 디자인 토큰은 src/app/globals.css@theme에 정의 (색상 코드는 Figma 팔레트 기준)
  • 브랜드 폰트 NordicClub (next/font/local), 로고/트럭 에셋은 public/
  • 백엔드 연동됨 — FastAPI 서버(NEXT_PUBLIC_API_BASE)와 통신. src/lib/api/가 그 경계.
  • 보드 상태의 진실 공급원은 여전히 store.tsx + localStorage다. 백엔드 세션은 인메모리라 서버 재시작 시 사라지므로, 백엔드를 DB가 아니라 파생 엔진으로 취급하고 응답을 로컬 상태에 병합한다.
  • mockData.ts는 삭제하지 않았다 — 시드 데이터 겸 장애 폴백이다.

실행

npm install
cp .env.example .env.local   # NEXT_PUBLIC_API_BASE 설정
npm run dev      # http://localhost:3000
npm run build    # 프로덕션 빌드 검증

백엔드는 배포된 개발 서버를 그대로 쓰면 된다(.env.example 기본값). CORS는 localhost:3000에서 통과한다.

개발 서버가 떠 있는 동안에는 npm run build를 돌리지 말 것 (.next 캐시 충돌로 500 발생). 타입만 볼 땐 npx tsc --noEmit.

화면 (라우트)

경로 화면 비고
/login 로그인 좌측 브랜드 그라데이션 패널 + 폼 / Google 로그인 (로그인 시 /로 이동)
/signup 회원가입 로그인과 동일한 split 카드 (가입 후 /userinfo로 이동)
/userinfo 기본 정보 가입 직후 기본 정보 수집 5단계 위저드 (완료 시 대시보드가 채워짐)
/ 대시보드 초기엔 빈 상태(온보딩) → 챗봇 Q&A(연령·지역) 완료 시 대시보드가 채워짐
/calendar 캘린더 월간 그리드 + 이벤트 + New event 폼 + 일정/체크리스트 (그룹)
/policy 정책 맞춤 정책 추천 상세 카드 2열 그리드 + 정렬 (PolicyDetailCard)
/admin 행정 맞춤 행정 절차 상세 카드 2열 그리드 + 정렬 (AdminDetailCard)

온보딩은 별도 페이지가 아니라 대시보드의 초기 상태(store.onboarded === false)이며, 완료하면 true로 저장되어 이후엔 바로 채워진 대시보드가 표시됨.

레이아웃 / UX

  • 그룹 패널: 카테고리(캘린더+일정 / 체크리스트 / 정책 / 행정)를 밝은 그룹(#1b1b1b) 안에 어두운 카드(#111)로 묶음
  • 페이지 세로 스크롤 없음: 콘텐츠는 뷰포트 높이에 고정되고, 요소가 많아지면 그룹 내부에서만 스크롤 (얇은 스크롤바)
  • 캘린더 그룹은 스크롤 없이 캘린더+오늘 일정을 항상 표시
  • 채팅 패널: 왼쪽 경계를 드래그해 너비 조절 가능. 최소 너비는 콘텐츠가 빈 공간 없이 차는 지점에 반응형으로 계산 (창 크기·콘텐츠 변화에 맞춰 재계산, localStorage 저장)
  • 진행바: 오른쪽에 짧게 배치, 트럭이 진행률을 따라 이동. 진행률은 체크리스트 완료율에서 파생

기능

  • 일정: 생성(New event)·수정(모달)·삭제, 캘린더 월 이동·날짜 선택
  • 체크리스트: 토글·추가·항목 수정/삭제, 목록 이름 변경·완료 삭제·비우기
  • 정책/행정 상세 카드: 핀 고정·숨기기·복원, 정렬(관련도순 등), "자세히 보기"·"신청하기"
  • 각 카드 미트볼(⋯) 메뉴로 수정/삭제
  • 챗: SSE 스트리밍으로 진행 단계 표시 → 실제 에이전트 응답. 연결 실패 시 POST 폴백, 서버 장애 시 캔드 응답 폴백
  • 로그인/회원가입/로그아웃 (JWT), 라우트 가드, 온보딩 완료/리셋
  • 이사 예정일 기준 D-day·마감 임박 알림

구조

src/
├─ app/
│  ├─ page.tsx            # 대시보드(+온보딩 초기 상태)
│  ├─ calendar/           # 캘린더
│  ├─ policy/ · admin/    # 정책 · 행정
│  ├─ login/              # 로그인
│  ├─ layout.tsx          # 폰트 로드 + MoveMateProvider
│  └─ globals.css         # @theme 디자인 토큰
├─ components/            # AuthLayout, WorkspaceLayout, TopNav, ProgressBanner,
│                         # GroupPanel, ScrollArea, DashboardView, MiniCalendar,
│                         # FullCalendar, TodayCard, ScheduleCard, ChecklistCard,
│                         # PolicyCard(대시보드 compact), PolicyDetailCard,
│                         # AdminDetailCard, cardParts, RecommendHeader,
│                         # RestoreCardsButton, NewEventForm, EventEditModal,
│                         # MeatballMenu, ChatPanel, Brand, icons
└─ lib/
   ├─ api/                # 백엔드 경계 — client·types·adapters·auth·chat·stream·schedule·session
   ├─ store.tsx           # React Context 상태 스토어 (localStorage 영속)
   ├─ mockData.ts         # 시드 데이터 + 타입 + 폴백 (PolicyItem·AdminItem·UserProfile 등)
   ├─ dates.ts            # 날짜 포맷 · 상대 날짜 라벨(그제~모레)
   ├─ lunar.ts            # 손없는 날(음력 끝자리 9·0) 판정
   └─ accents.ts          # 이벤트 색상 토큰 매핑

상태 전역 관리는 lib/store.tsxMoveMateProvider / useStore() 하나로 통일 (events·checklists·chat·정책 숨김·onboarded·auth).

백엔드 연동 상태

영역 상태
채팅 (POST + SSE) 완료
이사 일정 · 캘린더 · 체크리스트 완료 (수정 시 서버 역동기화)
인증 (회원가입·로그인·/me·가드) 완료
행정 카드 (/admin) 완료 — 일정 데이터의 필수 항목 기반
정책 카드 (/policy) 완료
계정별 보드 저장 (/api/v1/state) 완료 — 기기가 바뀌어도 따라온다
관리 콘솔 (/console) 완료 — 배포 빌드에서는 기본 꺼짐

설계 배경과 남은 과제는 MoveMMate/docs 저장소를 본다.

배포

Vercel에 올린다. 단, Vercel의 GitHub 연동은 쓰지 않는다 — 조직 소유 저장소를 Hobby 요금제에서 막기 때문이다. 대신 GitHub Actions가 직접 빌드해 올린다(.github/workflows/deploy.yml). Vercel은 GitHub을 보지 않으므로 저장소가 누구 것인지 따지지 않고, 저장소도 이 하나로 유지된다.

main push  →  Actions: vercel build --prod → vercel deploy --prebuilt --prod
PR         →  같은 흐름에서 --prod만 빠짐 (프리뷰 주소)

처음 한 번

npx vercel login
npx vercel link      # .vercel/project.json 에 orgId·projectId 가 생긴다

저장소 시크릿에 세 개를 넣는다.

시크릿 어디서
VERCEL_TOKEN Vercel → Account Settings → Tokens
VERCEL_ORG_ID .vercel/project.jsonorgId
VERCEL_PROJECT_ID projectId

NEXT_PUBLIC_*저장소가 아니라 Vercel 프로젝트 설정에 넣는다. vercel pull이 받아오므로 값이 한 군데에만 있게 된다.

변수
NEXT_PUBLIC_API_BASE https://d2t93gx9e6tmmx.cloudfront.net
NEXT_PUBLIC_ENABLE_CONSOLE 관리 콘솔을 배포본에서도 쓸 때만 true

.vercel/은 gitignore된다. 시크릿은 아니지만 계정에 묶인 값이라 저장소에 두지 않는다.

알아둘 것

  • NEXT_PUBLIC_*는 빌드 시점에 번들에 박힌다. 값을 바꾸면 재배포해야 반영된다.
  • 서버리스 함수가 0개다(전 페이지 정적). Hobby의 함수 타임아웃과 무관하고, 채팅 요청은 브라우저에서 CloudFront로 곧장 간다.
  • 배포 주소가 정해지면 백엔드 .envCORS_ORIGINS를 좁힌다. Vercel은 프리뷰마다 주소가 바뀌므로 CORS_ORIGIN_REGEX를 함께 쓴다. "*"를 빼지 않으면 아무것도 좁혀지지 않는다.

남은 TODO

  • 상단 검색창 실제 필터링
  • 구글 캘린더 이벤트 (google_events가 항상 빈 배열이라 미검증)
  • 토큰을 httpOnly 쿠키로 (BFF 프록시 도입 시)
  • 두 기기에서 동시에 고치면 나중에 저장한 쪽이 이긴다

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages