[feat] 기기 관리#9
Conversation
There was a problem hiding this comment.
Code Review
This pull request transitions the machine management system from mock data to real API integration, introducing hooks for machine operations and a new status management modal. It also implements a reservation countdown timer and updates various UI components. Review feedback primarily addresses an N+1 API call inefficiency, suggesting that reservation details be included in the list response to avoid multiple individual requests. Other feedback includes correcting a potential runtime error in data access, improving naming conventions for better clarity, and ensuring the new modal is responsive and uses intuitive iconography.
| export interface ReservationItem { | ||
| id: number; | ||
| machineId: number; | ||
| machine: string; | ||
| type: ReservationMachineType; | ||
| badgeStatus: BadgeStatus; |
There was a problem hiding this comment.
N+1 API 호출 문제를 해결하기 위해 ReservationItem 인터페이스에 사용자 정보와 예약 상태 관련 필드들을 추가하는 것이 좋습니다. 이렇게 하면 목록 조회 시 이미 포함된 데이터를 활용할 수 있어, 각 기기마다 상세 정보를 조회하기 위한 추가 API 호출을 제거할 수 있습니다.
export interface ReservationItem {
id: number;
machineId: number;
machine: string;
type: ReservationMachineType;
badgeStatus: BadgeStatus;
userName?: string;
userRoomNumber?: string;
expectedCompletionTime?: string;
status?: ReservationDTOStatus;
createdAt?: string;| return { | ||
| id: dto.id, | ||
| machineId: dto.machineId, | ||
| machine: dto.machineName, | ||
| type: getMachineType(dto.machineName), | ||
| badgeStatus, |
There was a problem hiding this comment.
DTO에서 추출한 사용자 및 예약 상세 정보를 ReservationItem에 매핑하여, 목록 데이터만으로도 화면에 필요한 정보를 표시할 수 있도록 합니다.
return {
id: dto.id,
machineId: dto.machineId,
machine: dto.machineName,
type: getMachineType(dto.machineName),
badgeStatus,
userName: dto.userName,
userRoomNumber: dto.userRoomNumber,
expectedCompletionTime: dto.expectedCompletionTime,
status: dto.status,
createdAt: dto.createdAt,| // 실제 예약 ID를 사용하여 상세 정보 조회 | ||
| const { data: reservationResponse } = useGetReservationDetail( | ||
| matchingReservation?.id ?? 0, | ||
| Boolean(matchingReservation), | ||
| ); | ||
|
|
||
| const reservation = reservationResponse?.data; |
There was a problem hiding this comment.
MachineRow 내부에서 useGetReservationDetail을 호출하는 것은 N+1 API 호출 문제를 발생시킵니다. 부모 컴포넌트에서 전달받은 reservations 목록에 이미 필요한 정보가 포함되어 있으므로(또는 포함되도록 수정하여), 이를 직접 사용하도록 변경해야 합니다.
| // 실제 예약 ID를 사용하여 상세 정보 조회 | |
| const { data: reservationResponse } = useGetReservationDetail( | |
| matchingReservation?.id ?? 0, | |
| Boolean(matchingReservation), | |
| ); | |
| const reservation = reservationResponse?.data; | |
| const reservation = matchingReservation; |
| <MachineRow | ||
| key={item.id} | ||
| item={item} | ||
| reservations={reservations ?? []} |
There was a problem hiding this comment.
useGetReservations가 반환하는 reservations는 API 응답 객체일 가능성이 높습니다. MachinesPage에서와 마찬가지로 reservations?.data.reservations와 같이 실제 배열 데이터에 접근해야 합니다. 현재 코드대로라면 reservations ?? []는 배열이 아닌 객체를 전달하게 되어 런타임 에러가 발생할 수 있습니다.
| reservations={reservations ?? []} | |
| reservations={reservations?.data.reservations ?? []} |
| prev === item.name ? null : item.name, | ||
| ) | ||
| } | ||
| onDelete={() => |
| const overlayPositionClass = | ||
| side === "right" | ||
| ? "absolute left-[calc(100%+16px)] top-0 h-full w-full" | ||
| : "absolute right-[calc(100%+16px)] top-0 h-full w-full"; |
| className="inline-flex h-9 w-9 items-center justify-center rounded-full cursor-pointer border-2 border-[#EF4B4F] text-[#EF4B4F] disabled:cursor-not-allowed disabled:opacity-50" | ||
| > | ||
| <Trash2 size={16} strokeWidth={2.2} /> | ||
| <Gavel size={16} strokeWidth={2.2} /> |
개요 💡
기기 관리 페이지를 제작했습니다.
작업내용 ⌨️
다음과 같은 내용을 작업했습니다,