Skip to content

[user] 사용자 홈 화면 v1 디자인 이식 - #32

Merged
jjhhss100906 merged 3 commits into
mainfrom
feat/user-main-page
Oct 8, 2026
Merged

jjhhss100906 merged 3 commits into
mainfrom
feat/user-main-page

Conversation

@jjhhss100906

Copy link
Copy Markdown
Contributor

개요 💡

v1 사용자 웹 홈 화면을 디자인 그대로 옮기고, 데이터는 v2 API로 연결합니다. (#31 위에 쌓은 PR입니다)

작업내용 ⌨️

  • widgets/user-main-page/UserMainPage (v1 app/page.tsx 기준)
    • 통계 카드: 전체 / 가능 / 사용중
    • 서비스 이용 제한 알림: GET /reservations/availability의 canReserve = false일 때 해제 시각과 사유(예약 패널티 / 호실 세탁 금지) 표시
    • 내 예약 현황: 호실 활성 예약(GET /reservations/active/room)을 v1 예약 카드로 표시
    • 당겨서 새로고침(5초 쿨다운), polling(기기 30초 · 예약 10초)
    • 451(이용 대상 아님) 응답 시 서버 메시지 표시
  • widgets/user-main-page/ui/MyReservationCard (v1 reservation-card 기준)
    • 기기 작업 상태, 호실, 예약/시작 시간, 남은 시간(HH:MM:SS)
    • RESERVED: 예약 후 5분까지 남은 시간, RUNNING: 완료 예정까지 남은 시간
    • 예약 확정("세탁할게요") 버튼 제거 — v2에서는 기기 동작 시 서버가 RUNNING으로 전환
    • 예약 취소는 내 예약(RESERVED)에만 표시
  • features/reservation/cancel-my-reservation: 예약 취소 버튼, 패널티 적용 시 재예약 가능 시각 안내
  • shared/hooks/usePullToRefresh, shared/hooks/useNow, shared/lib/formatCountdown 추가

검증:

  • node --experimental-strip-types --test tests/*.test.mjs: 25 tests 통과
  • biome lint ., tsc --noEmit: 통과
  • 로컬에서 임시 경로로 실제 서버 데이터 렌더링 확인 (전체 24대 / 가능 24대 / 사용중 0대)

참고:

  • 라우트((user)/main)는 (user) 그룹과 사용자 레이아웃이 추가된 뒤 연결합니다.
  • 세탁기 / 건조기 탭(v1 "기기 예약" 카드)은 다음 PR에서 이 화면 하단에 추가합니다.
  • 현재 로그인 콜백이 /(관리자 레이아웃)로 이동해 학생 계정은 /app-download로 보내지므로, (user) 분리 시 콜백 이동 경로도 함께 조정이 필요합니다.

🤖 Generated with Claude Code

- 통계 카드, 이용 제한 알림, 내 예약 현황 카드
- 예약 취소(예약 확정 버튼 제거), 당겨서 새로고침, polling

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

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
washer Ready Ready Preview Oct 8, 2026 3:31am UTC

Request Review

@inryeok-bot inryeok-bot 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.

리뷰 결과

변경된 9개 파일을 검토했습니다.

심각도 개수
Critical 0
High 0
Medium 0
Low 0

유형: 필수 수정 0, 수정 권장 0, 제안 0, 확인 질문 0, 좋았던 점 0

완료

수정이 필요한 문제를 찾지 못했습니다. 검증 가능한 인라인 관찰은 생성하지 않았습니다 (NO_VALID_INLINE_OBSERVATION).

검토한 head: 7eda56398e23 · 최신 head에서 다시 검토하려면 /review를 작성하세요.

Comment thread src/shared/hooks/useNow.ts Outdated

// 초 단위 카운트다운을 위해 현재 시각을 주기적으로 갱신한다.
export function useNow(intervalMs = 1000): number {
const [now, setNow] = useState(() => Date.now());

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.

UserMainPage에서 useNow()로 받은 값을 MyReservationCard의 남은 시간 계산에 바로 사용하고 있는데, 초기값이 Date.now()로 설정되어 있습니다.

Next.js의 Client Component도 초기 HTML은 서버에서 pre-render될 수 있기 때문에 서버 렌더 시각과 브라우저 hydration 시각이 달라질 수 있습니다. 활성 예약이 있는 경우 서버와 클라이언트의 formatCountdown() 결과가 달라져 hydration mismatch가 발생할 가능성이 있습니다.

초기 now를 null로 두고 mount 이후 Date.now()를 설정하거나, mount가 완료되기 전에는 카운트다운을 렌더링하지 않는 방식이 안전해 보입니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

반영했습니다. useNow가 mount 전에는 null을 반환하도록 바꾸고, now가 null이면 남은 시간을 렌더링하지 않도록 했습니다. 수정 커밋: 0c4cf08

if (!value) return "-";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return "-";
return date.toLocaleTimeString("ko-KR", {

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.

formatDateTime()과 formatClock()에서 toLocaleString/toLocaleTimeString에 timeZone을 지정하지 않고 있습니다.

백엔드 응답은 timezone 정보가 없는 LocalDateTime 문자열이고, 서버와 브라우저가 서로 다른 timezone으로 실행될 수 있어 예약 시간이 서버 렌더링과 브라우저 렌더링에서 다르게 표시될 가능성이 있습니다.

서비스 기준 timezone이 한국 시간이라면 Asia/Seoul을 명시하거나, 공통 날짜 포맷터에서 timezone을 일관되게 처리하는 방향을 확인 부탁드립니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

반영했습니다. shared/lib/kstDateTime.ts를 추가해 offset 없는 LocalDateTime은 +09:00(한국 시간)으로 해석하고, 표시는 timeZone: "Asia/Seoul"로 통일했습니다. 남은 시간 계산(getReservedDeadline)도 같은 파서로 해석한 값을 받도록 바꿨고, UTC · America/New_York 환경에서도 테스트가 통과하는 것 확인했습니다. 수정 커밋: 0c4cf08

- useNow는 mount 전 null을 반환하고 카운트다운은 mount 후에만 표시
- 백엔드 LocalDateTime을 한국 시간(+09:00)으로 해석, Asia/Seoul로 표시
- getReservedDeadline은 해석된 Date를 받도록 변경

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jjhhss100906 added a commit that referenced this pull request Oct 8, 2026
- 룸메이트 예약을 내 예약으로 표시하지 않도록 활성 예약 ID와 기기 reservationId 비교
- 호실 예약의 기기 종류를 machineId로 조회하고 이름 추정은 대체 수단으로만 사용
- 카운트다운 · 예약 만료 계산에 한국 시간 해석 적용 (#32 수정 반영)

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

Copy link
Copy Markdown
Contributor

현재 PR은 #30 → #31 → #32 → #33 순서로 스태킹되어 있습니다. Approve는 가능하지만, 실제 머지 시에는 하위 PR부터 순서대로 반영하고 각 단계마다 다음 PR의 base, diff, CI를 재확인해 주세요. Approve가 머지를 의미하는 것은 아닙니다.

Base automatically changed from feat/user-ui-base to main October 8, 2026 03:30
@jjhhss100906
jjhhss100906 merged commit 3343114 into main Oct 8, 2026
3 checks passed
@jjhhss100906
jjhhss100906 deleted the feat/user-main-page branch October 8, 2026 04:32

This branch was successfully deployed

1 active deployment
Preview — abdeabb2 Deployed Oct 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants