Skip to content

[Feat] MainPage & ReservationPage#8

Merged
bom0320 merged 23 commits into
developfrom
feat/main
Apr 13, 2026
Merged

[Feat] MainPage & ReservationPage#8
bom0320 merged 23 commits into
developfrom
feat/main

Conversation

@bom0320

@bom0320 bom0320 commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

개요 💡

MainPage와 ReservationPage를구현하고, 예약 히스토리 조회를 위한 overlay UI 및 상태 배지 구조를 정리했습니다.

작업내용 ⌨️

  • MainPage API 연동 및 데이터 기반 UI 구성 (reports / users / reservations)
  • ReservationPage 구현 (세탁기 / 건조기 예약 현황 분리)
  • 예약 히스토리 overlay UI 구현
    • 패널 기준 좌/우 overlay 위치 제어
    • 외부 클릭 시 닫힘 처리 (useOutsideClick 훅 적용)
  • ReservationHistoryCard 컴포넌트 분리
  • 상태 배지(ReservationStatusBadge) 구조 통합
    • 현재 상태 / 히스토리 상태 공통 UI로 통합

@bom0320 bom0320 changed the title Feat/main [Feat] MainPage & ReservationPage Apr 9, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request transitions the admin dashboard from mock data to real API integration using React Query and Axios. It introduces several new API services, data mappers, and UI components like the reservation history modal. Key feedback includes concerns regarding the removal of Next.js rewrites which may impact API routing, security risks associated with disabling TLS validation in development, and potential logic errors in status mapping functions for reservations and history. Additionally, there are suggestions to handle breaking type changes in report models and to refine Axios interceptor logic.

I am having trouble creating individual review comments. Click here to see my feedback.

next.config.ts (11-17)

high

rewrites 설정이 제거되었습니다. /api/:path* 경로가 process.env.NEXT_PUBLIC_API_URL/:path*로 재작성되지 않게 됩니다. 만약 애플리케이션이 API 호출을 위해 이 재작성 기능에 의존하고 있었다면, 이를 제거하면 API 요청이 실패할 수 있습니다. axios.ts 파일에서 process.env.NEXT_PUBLIC_API_URL을 직접 사용하는 것은 좋은 변경이지만, rewrites 제거가 의도된 것이며 다른 부분에 영향을 미치지 않는지 확인해야 합니다. (예: 서버 측 API 호출 또는 다른 Next.js 기능).

package.json (7)

high

NODE_TLS_REJECT_UNAUTHORIZED=0를 사용하여 TLS 인증서 유효성 검사를 비활성화하는 dev:insecure 스크립트가 추가되었습니다. 개발 환경에서 자체 서명된 인증서를 사용할 때 편리할 수 있지만, 프로덕션 환경에서 실수로 사용되거나 개발자들이 인증서 경고를 무시하는 데 익숙해지면 심각한 보안 위험이 될 수 있습니다. 일반적으로 신뢰할 수 있는 인증서를 올바르게 구성하거나 TLS 종료를 안전하게 처리하는 프록시를 사용하는 것이 좋습니다.

src/shared/lib/axios.ts (6-7)

high

baseURLprocess.env.NEXT_PUBLIC_API_URL로 설정된 것은 외부 API 호출에 좋은 변경입니다. 하지만 next.config.ts 파일에서 /api/:path*에 대한 rewrites 설정이 제거되었습니다. 만약 NEXT_PUBLIC_API_URL이 외부 URL이라면, 클라이언트 측 axiosInstance에서 직접 호출하는 것은 외부 API 엔드포인트를 클라이언트에 직접 노출시키거나 CORS 정책을 우회할 수 있는 보안 문제가 될 수 있습니다. 의도된 네트워크 아키텍처를 명확히 할 필요가 있습니다.

src/entities/report/model/types.ts (8-9)

medium

ReportItem 인터페이스에서 timereason 필드가 선택적(?:)에서 필수(:)로 변경되었습니다. 이는 기존 코드에서 이 필드들이 선택적이라고 가정하고 사용하고 있었다면 호환성 문제가 발생할 수 있는 변경입니다. ReportItem을 사용하는 모든 곳에서 이 필드들이 제공되는지 확인하거나, 선택적 속성이 여전히 필요한 경우 변경을 되돌려야 합니다.

src/entities/reservation/lib/mapReservation.ts (70-84)

medium

mapBadgeStatus 함수에서 dto.statusCOMPLETED 또는 CANCELLED일 때 machineAvailabilityUNAVAILABLE이 아니라면, 이 함수는 잘못되게 "예약중"을 반환합니다. 이는 과거 예약 상태를 잘못 나타낼 수 있습니다. 모든 가능한 dto.status 값에 대해 명시적으로 처리하거나, 모든 경우에 대해 원하는 배지 상태를 정확하게 반영하도록 로직을 개선해야 합니다.

src/entities/reservation/lib/mapReservationHistory.ts (30-37)

medium

mapHistoryStatus 함수에서 default 케이스가 "사용 완료"를 반환합니다. 하지만 MachineReservationHistoryItemDTO["status"] 타입에는 "RESERVED"와 "IN_USE"가 포함되어 있습니다. 만약 히스토리 항목의 status가 "RESERVED" 또는 "IN_USE"라면, 잘못되게 "사용 완료"로 매핑될 것입니다. 이는 과거 예약 상태를 잘못 나타낼 수 있습니다.

src/shared/lib/axios.ts (47-49)

medium

Axios 응답 인터셉터에서 error.config (즉 originalRequest)는 항상 정의됩니다. 이 조건문 if (!originalRequest)은 항상 false로 평가되므로 불필요한 코드입니다. 이 검사는 제거하는 것이 좋습니다.

src/shared/lib/axios.ts (94-95)

medium

console.error(error)return Promise.reject(refreshError)로 변경하여 오류 전파를 개선한 것은 좋습니다. 하지만 새로고침 토큰 실패에 대한 로깅이 여전히 필요하다면, Promise.reject를 호출하기 전에 로깅을 추가하는 것을 고려해야 합니다.

src/widgets/reservations-page/ui/ReservationStatusPanel.tsx (24-26)

medium

예약이 없을 때 표시되는 메시지(현재 활성화된 예약이 없습니다.)를 포함하는 divh-full 클래스가 적용되어 있습니다. 이는 부모 컨테이너의 높이에 따라 의도치 않은 레이아웃 문제를 일으킬 수 있습니다. 부모 컨테이너의 높이가 제한되어 있거나, 더 유연한 높이 설정을 사용하는 것이 좋습니다.

@bom0320 bom0320 requested a review from LeeSangHyeok0731 April 9, 2026 09:15
@LeeSangHyeok0731

Copy link
Copy Markdown
Contributor

@gemini-code-assist 코드리뷰 다시 해줘. 너무 가독성이 떨어져

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request significantly refactors the application to integrate with a backend API for dashboard summaries, reports, reservations, and user management. Key changes include introducing axiosInstance with an interceptor for token refresh, defining new DTOs and mapping functions for API responses, and updating UI components like AdminLayout, MainPage, and ReservationsPage to fetch and display live data using react-query. A new ReservationHistoryModal was added, and reservation actions now include history viewing and deletion. Review comments suggest making the API timeout configurable, re-adding error logging in the axios interceptor, and replacing window.confirm with a more user-friendly modal for deletion actions.

Comment thread src/shared/lib/axios.ts Outdated
export const axiosInstance = axios.create({
baseURL: "/",
baseURL: process.env.NEXT_PUBLIC_API_URL,
timeout: 10000,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

A timeout of 10 seconds is defined, but it is not clear if this is appropriate for all API endpoints. Consider if this should be configurable or if it might be too short for certain operations.

Comment thread src/shared/lib/axios.ts
Comment on lines +94 to +95
} catch (refreshError) {
return Promise.reject(refreshError);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Returning a rejected promise in the catch block is good, but consider logging the error for debugging purposes before rejecting, as the original code did.

};

const handleDelete = () => {
const confirmed = window.confirm("이 예약을 강제 취소하시겠습니까?");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using window.confirm is a blocking operation and not ideal for a modern React application. Consider using a custom modal or a toast notification for better user experience.

@bom0320 bom0320 merged commit 7a5251a into develop Apr 13, 2026
1 check passed
@bom0320 bom0320 deleted the feat/main branch April 13, 2026 05:59
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