Skip to content

[user] 세탁기 · 건조기 목록과 배치도, 예약하기 v1 디자인 이식 - #33

Merged
jjhhss100906 merged 3 commits into
mainfrom
feat/user-machine-list
Oct 8, 2026
Merged

jjhhss100906 merged 3 commits into
mainfrom
feat/user-machine-list

Conversation

@jjhhss100906

Copy link
Copy Markdown
Contributor

개요 💡

v1 홈 하단의 "기기 예약" 카드(세탁기 / 건조기 탭)를 디자인 그대로 옮기고, 예약은 v2 API로 연결합니다. (#32 위에 쌓은 PR입니다)

작업내용 ⌨️

  • widgets/user-machine-list
    • MachineReservationSection: v1 "기기 예약" 카드와 세탁기 / 건조기 탭
    • MachineList: 층별 그룹, 층 헤더(대수 배지 · 새로고침 5초 쿨다운 · 배치도), 카드 그리드
    • MachineCard: v1 기기 카드 (상태 배지, 위치, 작업 상태, 예약 호실 · 내 예약 표시, 남은 시간, 예약 불가 안내)
    • LayoutModal: v1 배치도 모달 (건조기 위 / 세탁기 아래, 입구 표시). 층에 기기가 더 있으면 칸이 늘어나도록 처리
  • features/reservation/reserve-machine: 예약하기 버튼 (POST /api/v2/reservations)
    • 호실 세탁 금지 · 패널티 · 1인 1예약 · 호실 동일 종류 예약이면 버튼 비활성화 후 v1과 같은 위치에 사유 표시
  • UserMainPage에 machineSection 슬롯 추가
    • 같은 레이어(widget)끼리 import하지 않도록 페이지에서 <UserMainPage machineSection={<MachineReservationSection />} />로 조립
  • v1 대비 변경
    • 상태: v2에 맞춰 "확정됨" 제거, "통세척 중"(CLEANING) · "사용 불가" 추가
    • 예약 성공 후 마이페이지 이동 대신 현재 화면 유지 (홈의 내 예약 현황에 바로 표시)

검증:

  • node --experimental-strip-types --test tests/*.test.mjs: 25 tests 통과
  • biome lint ., tsc --noEmit: 통과
  • 로컬 임시 경로에서 실제 서버 데이터로 렌더링 확인 (3층 / 4층 세탁기 6대씩, 탭 · 배치도 · 새로고침)

참고:

  • 고장 신고 · 히스토리 버튼은 다음 PR에서 카드 버튼 영역(renderActions)에 추가합니다.

🤖 Generated with Claude Code

- 홈 하단 기기 예약 카드(세탁기 / 건조기 탭)
- 층별 기기 카드 그리드, 배치도 모달, 예약하기와 예약 불가 안내

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 4:32am 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개 파일을 검토했고 인라인 관찰 1개를 남겼습니다.

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

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

주요 관찰

  • 필수 수정 · HIGH 예약 섹션이 어떤 호출부에서도 주입되지 않습니다

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

</CardContent>
</Card>
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 필수 수정 · HIGH

예약 섹션이 어떤 호출부에서도 주입되지 않습니다

machineSection은 선택적 prop이라 전달되지 않으면 이 위치에서 아무것도 렌더링하지 않습니다. 이번 PR에는 MachineReservationSection을 생성해 이 prop으로 넘기는 호출부 변경이 없으므로, 추가된 예약 목록과 예약 버튼 전체가 사용자에게 노출되지 않습니다.

이유: 구현된 기능이 런타임 화면에서 완전히 도달 불가능한 상태입니다.

제안: 실제 사용자 라우트에서 예약 섹션을 연결하고 화면에 표시되는지 확인하는 렌더링 테스트를 추가하세요.

Suggested change
<MachineReservationSection />

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.

(user) 라우트 그룹이 아직 없어서 의도적으로 호출부를 넣지 않았습니다. (user) 그룹과 사용자 레이아웃이 추가되면 <UserMainPage machineSection={<MachineReservationSection />} />로 라우트를 연결할 예정이고, 그 전까지는 로컬 임시 경로에서 렌더링을 확인했습니다.

machine={machine}
now={now}
isMyRoomMachine={
myRoomNumber !== null && machine.roomNumber === myRoomNumber

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.

isMyRoomMachine을 machine.roomNumber === myRoomNumber로 판별하고 있는데, /api/v2/reservations/active/room은 현재 사용자 본인뿐 아니라 같은 호실 룸메이트의 활성 예약도 반환합니다.

따라서 같은 호실 룸메이트가 예약한 기기도 MachineCard에서 (내 예약)으로 표시될 수 있습니다. 실제 표시 위치는 MachineCard의 isMyRoomMachine ? "(내 예약)" : "예약" 분기입니다.

activeReservationQuery.data?.id === machine.reservationId 또는 현재 사용자 ID와 machine.userId를 비교해서 본인 예약 여부를 판단하는 게 맞는지 확인 부탁드립니다.

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.

맞습니다, 반영했습니다. 호실 번호 대신 activeReservation.id === machine.reservationId로 본인 예약 여부를 판단하도록 바꿔서 룸메이트 예약은 "예약"으로만 표시됩니다. 수정 커밋: 9ad9b80

canReserve: availability.canReserve,
isBanned: availability.isBanned,
hasMyActiveReservation: activeReservationQuery.data !== null,
roomReservationTypes: roomReservations.map((reservation) =>

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.

호실 내 동일 종류 예약 제한을 getMachineTypeFromName(reservation.machineName)으로 판단하고 있습니다.

그런데 백엔드의 호실 활성 예약 응답은 machineId와 machineName을 제공하고, 기기 타입을 별도 필드로 제공하지 않습니다. 기기명이 Washer-3F-L1이 아닌 세탁기 1처럼 내려오면 getMachineTypeFromName()이 null을 반환합니다.

이후 getReserveBlockReason()에서 roomReservationTypes.includes(machineType)를 검사하기 때문에, 같은 호실에 이미 세탁기 예약이 있어도 동일 종류 예약 제한이 적용되지 않을 수 있습니다.

machineId로 allMachines의 타입을 조회하거나, 백엔드 응답에 machineType을 포함하는 방식이 안전해 보입니다.

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.

반영했습니다. 호실 예약의 기기 종류는 machineId로 기기 현황 목록에서 먼저 찾고, 찾지 못할 때만 이름으로 추정하도록 바꿨습니다. 수정 커밋: 9ad9b80

- 룸메이트 예약을 내 예약으로 표시하지 않도록 활성 예약 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-main-page to main October 8, 2026 04:31
@jjhhss100906
jjhhss100906 merged commit 6b4f684 into main Oct 8, 2026
3 checks passed
@jjhhss100906
jjhhss100906 deleted the feat/user-machine-list branch October 8, 2026 04:33

This branch was successfully deployed

1 active deployment
Preview — 80f14a86 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