Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Code Review
This pull request centralizes date and time formatting across the application using a new dateTime service, supports multiple image uploads (up to 10) during product registration, and refactors chat room creation to navigate directly to newly created rooms. Feedback from the review highlights three key areas for improvement: parallelizing image uploads using Promise.all to enhance performance, adding double-click protection in src/app/page.tsx to prevent duplicate chat room creation from race conditions, and caching Intl.DateTimeFormat instances in the new dateTime service to reduce initialization overhead during list rendering.
| const uploadedImages: ProductImagePayload[] = []; | ||
| for (let index = 0; index < filesToUpload.length; index += 1) { | ||
| const file = filesToUpload[index]; | ||
| const uploadedImage = await currentServices.uploadImage( | ||
| file, | ||
| images.length + index + 1, | ||
| ); | ||
| uploadedImages.push(uploadedImage); | ||
| } |
There was a problem hiding this comment.
🚀 성능 개선 제안: 이미지 병렬 업로드
현재 코드는 for 루프를 사용하여 여러 이미지를 순차적으로 업로드하고 있습니다. 이 방식은 업로드할 이미지 개수가 많아질수록 대기 시간이 선형적으로 증가하여 사용자 경험(UX)에 부정적인 영향을 줄 수 있습니다.
Promise.all을 사용하여 이미지 업로드를 병렬로 처리하면 네트워크 대역폭을 효율적으로 활용하여 업로드 속도를 크게 향상시킬 수 있습니다.
참고 (저장소 스타일 가이드 6번):
성능 이슈가 생길 만한 부분은 반드시 지적할 것
const uploadedImages = await Promise.all(
filesToUpload.map((file, index) =>
currentServices.uploadImage(file, images.length + index + 1)
)
);
References
- 성능 이슈가 생길 만한 부분은 반드시 지적할 것 (link)
| const roomId = | ||
| existingRoom?.roomId ?? (await createChatRoom({ productId: chatProductId })).roomId; |
There was a problem hiding this comment.
⚠️ 더블 클릭으로 인한 중복 채팅방 생성 버그 위험 (레이스 컨디션)
src/app/products/[productId]/page.tsx나 src/app/auctions/[auctionId]/page.tsx에서는 isOpeningChat 상태를 두어 더블 클릭 및 중복 요청을 방지하고 있습니다.
하지만 현재 src/app/page.tsx의 openProductChat 함수에는 이러한 방어 코드가 누락되어 있습니다. 사용자가 채팅 버튼을 빠르게 여러 번 누를 경우, createChatRoom이 동시에 여러 번 호출되어 동일한 상품에 대해 여러 개의 채팅방이 중복 생성되는 버그가 발생할 수 있습니다.
App 컴포넌트에도 isOpeningChat 상태(또는 useRef 플래그)를 추가하여 중복 진입을 막아주세요.
| const formatter = new Intl.DateTimeFormat("en-CA", { | ||
| timeZone: "Asia/Seoul", | ||
| year: "numeric", | ||
| month: "2-digit", | ||
| day: "2-digit", | ||
| hour: "2-digit", | ||
| minute: "2-digit", | ||
| second: options.includeSecond ? "2-digit" : undefined, | ||
| hourCycle: "h23", | ||
| }); |
There was a problem hiding this comment.
🚀 성능 개선 제안: Intl.DateTimeFormat 인스턴스 캐싱
Intl.DateTimeFormat 생성자는 내부적으로 매우 무거운 연산을 수행하므로, 매번 함수가 호출될 때마다 새로운 인스턴스를 생성하는 것은 성능에 큰 부담을 줍니다. 특히 이 함수는 구매/판매 내역 및 지갑 내역 등 목록을 렌더링할 때 반복적으로 호출되므로 성능 저하(CPU 부하 및 렌더링 지연)의 원인이 될 수 있습니다.
options.includeSecond 값에 따라 미리 생성된 포맷터 인스턴스를 모듈 레벨에서 캐싱하여 재사용하는 것을 권장합니다.
참고 (저장소 스타일 가이드 6번):
성능 이슈가 생길 만한 부분은 반드시 지적할 것
References
- 성능 이슈가 생길 만한 부분은 반드시 지적할 것 (link)
There was a problem hiding this comment.
Pull request overview
This PR addresses several frontend issue fixes across chat entry flows, product registration, API datetime display, navigation layout, and auction bidding UI.
Changes:
- Centralizes API datetime parsing/formatting and applies it across services/screens.
- Updates chat flows to create/open real chat rooms immediately and updates chat empty-state copy.
- Adds multi-image product upload, bidding-status profile/animation updates, SSE URL/default config fixes, and layout adjustments.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/services/dateTime.ts |
Adds shared API date parsing/formatting utilities. |
src/services/wishlist/service.ts |
Uses shared API timestamp sorting. |
src/services/wallet/service.ts |
Uses shared API date parts parsing/formatting. |
src/services/sales-management/service.ts |
Uses shared API timestamps for status/sorting. |
src/services/review/service.ts |
Uses shared API date formatting for review labels. |
src/services/recent-products/service.ts |
Uses shared API timestamp parsing for viewed time. |
src/services/product/search/service.ts |
Uses shared API timestamp parsing for auction end labels. |
src/services/mypage/sales-history/service.ts |
Uses shared API date parts formatting. |
src/services/mypage/purchase-history/service.ts |
Uses shared API date parts formatting. |
src/services/events/stream.ts |
Adjusts SSE URL fallback behavior for deployed environments. |
src/services/chats/service.ts |
Uses shared API date parsing/formatting for chat time labels. |
src/services/buying-auction/service.ts |
Uses shared API timestamp parsing for auction labels. |
src/services/auction/list/service.ts |
Uses shared API timestamp parsing for auction end labels. |
src/services/auction/detail/types.ts |
Adds bidder profile image URL to bid history items. |
src/services/auction/detail/service.ts |
Uses shared API timestamps for remaining-time calculation. |
src/components/transaction-receipt/TransactionReceipt.tsx |
Uses shared API datetime formatting in receipts. |
src/app/products/register/RegisterScreen.tsx |
Adds max-10 multi-image upload handling. |
src/app/products/register/index.tsx |
Enables multiple file selection. |
src/app/products/[productId]/receipt/index.tsx |
Uses shared API datetime formatting. |
src/app/products/[productId]/page.tsx |
Creates a real chat room before navigating. |
src/app/products/[productId]/index.tsx |
Uses shared API datetime utilities in auction detail timing. |
src/app/page.tsx |
Updates app-level chat navigation to create/select real chat rooms. |
src/app/chats/index.tsx |
Updates chat empty-state copy. |
src/app/chats/[roomId]/index.tsx |
Uses shared API timestamp sorting/formatting for messages. |
src/app/auctions/[auctionId]/page.tsx |
Creates chat rooms before navigation and formats reauction expiry. |
src/app/auctions/[auctionId]/bidding-status/index.tsx |
Adds bidder avatars and ranking animations; updates datetime sorting/formatting. |
src/app/(main)/notifications/index.tsx |
Uses shared API date parsing/formatting for notification time labels. |
src/app/(main)/index.tsx |
Animates bottom-nav padding when the nav hides. |
src/app/(main)/home/index.tsx |
Makes popular product row horizontally scrollable. |
next.config.mjs |
Changes default API base URL to the production API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function getApiTime(value: string | null | undefined): number { | ||
| return parseApiDate(value)?.getTime() ?? 0; |
| const uploadedImages: ProductImagePayload[] = []; | ||
| for (let index = 0; index < filesToUpload.length; index += 1) { | ||
| const file = filesToUpload[index]; | ||
| const uploadedImage = await currentServices.uploadImage( | ||
| file, | ||
| images.length + index + 1, | ||
| ); | ||
| uploadedImages.push(uploadedImage); | ||
| } | ||
|
|
변경 사항
🎲 Issue Number
close #116