-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor/64: 로딩/에러 처리 #68
Conversation
Walkthrough이 변경 사항은 거래 API 기능을 포함한 여러 컴포넌트에서의 수정 사항을 포함합니다. Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (8)
src/app/search/[id]/_components/transaction-form/edit-cancel/edit-table-body.tsx (1)
30-38
: 색상 값을 상수로 분리하는 것을 고려해보세요.매수/매도 색상 값을 상수로 분리하면 유지보수성이 향상될 것 같습니다.
다음과 같이 리팩토링하는 것을 제안드립니다:
+const ORDER_TYPE_COLORS = { + 매수: 'text-[#F20000]', + 매도: 'text-[#4882FA]', +} as const; <span className={cn( "pr-3", - data.type === "매수" && "text-[#F20000]", - data.type === "매도" && "text-[#4882FA]", + ORDER_TYPE_COLORS[data.type as keyof typeof ORDER_TYPE_COLORS] )} >src/app/search/[id]/_components/transaction-form/history.tsx (2)
32-47
: 정렬 로직 최적화를 제안드립니다.매 렌더링마다 정렬이 실행되는 것을 방지하기 위해
useMemo
를 사용하는 것이 좋을 것 같습니다.다음과 같이 개선하는 것을 제안드립니다:
+const sortedTradeHistory = useMemo( + () => + tradeHistoryData + ? [...tradeHistoryData].sort((a, b) => b.id - a.id) + : [], + [tradeHistoryData] +); -{tradeHistoryData && tradeHistoryData?.length > 0 ? ( - [...tradeHistoryData] - .sort((a, b) => b.id - a.id) +{sortedTradeHistory.length > 0 ? ( + sortedTradeHistory
50-56
: 이미지 크기를 상수로 분리하는 것을 추천드립니다.이미지 크기 값을 상수로 분리하면 일관성 있는 관리가 가능할 것 같습니다.
다음과 같이 개선하는 것을 제안드립니다:
+const WALLET_IMAGE = { + width: 150, + height: 150, +} as const; <Image src="/images/green-wallet.png" - width={150} - height={150} + width={WALLET_IMAGE.width} + height={WALLET_IMAGE.height} className="mx-auto mb-30 mt-65" alt="지갑 그림" />src/app/search/[id]/_components/transaction-form/index.tsx (2)
32-39
: 로딩 상태 UI 개선이 필요합니다.로딩 상태 UI가 전체 컴포넌트의 높이를 차지하고 있어 불필요한 공간을 차지합니다. 로딩 스피너의 위치를 중앙으로 조정하는 것이 좋겠습니다.
- <div className="ml-17 h-630 min-w-450 rounded-10 bg-white px-22 py-30"> + <div className="ml-17 min-w-450 rounded-10 bg-white px-22 py-30"> <h3 className="mb-250 text-20-700">거래하기</h3> - <LoadingSpinner /> + <LoadingSpinner className="mt-20" /> </div>
77-99
: 비인증 상태의 UI/UX 개선이 필요합니다.로그인이 필요한 상태에서 사용자 경험을 더욱 개선할 수 있습니다:
- 로그인 버튼에 hover 효과 추가
- 이미지 alt 텍스트를 더 명확하게 수정
<Image src="/images/login-guard.png" - alt="보안 아이콘" + alt="로그인 필요 안내 이미지" width={300} height={300} className="absolute right-1/2 top-40 translate-x-1/2" /> <Link href="/login" - className="m-auto mt-40 block w-150 rounded-4 bg-[#11E977] py-16 text-center text-16-700" + className="m-auto mt-40 block w-150 rounded-4 bg-[#11E977] py-16 text-center text-16-700 transition-colors hover:bg-[#0fd066]" >src/api/transaction/index.ts (2)
261-268
: 인터페이스 속성에 대한 문서화가 필요합니다.TradeHistory 인터페이스의 각 속성에 대한 설명이 없어 사용하기 어려울 수 있습니다.
export interface TradeHistory { + /** 거래 고유 식별자 */ id: number; + /** 매수/매도 가격 */ buyPrice: number; + /** 남은 수량 */ remainCount: number; + /** 총 거래 수량 */ stockCount: number; + /** 주식 종목명 */ stockName: string; + /** 매수/매도 주문 타입 */ buyOrder: string; }
Line range hint
271-292
: 에러 처리 로직 개선이 필요합니다.
- 빈 에러 메시지는 디버깅을 어렵게 만듭니다.
- API 응답 실패 시 더 구체적인 에러 메시지가 필요합니다.
if (token === null) { - throw new Error(); + throw new Error("인증 토큰이 없습니다."); } const response = await fetch( `${process.env.NEXT_PUBLIC_API_URL}/api/account/accounts/save/${stockName}`, { headers: { Authorization: `Bearer ${token}`, }, }, ); if (!response.ok) { - throw new Error("Failed to fetch stocks"); + const errorData = await response.text(); + throw new Error(`거래 내역을 불러오는데 실패했습니다. (${response.status}: ${errorData})`); }src/app/search/[id]/_components/transaction-form/trade/index.tsx (1)
97-101
: 에러 메시지를 더 구체적으로 개선하면 좋겠습니다.현재 에러 메시지가 너무 일반적입니다. 다음과 같이 구체적인 상황별 메시지를 제공하는 것이 좋겠습니다:
- showToast(error.message, "error"); + showToast( + error.code === "INSUFFICIENT_BALANCE" + ? "잔액이 부족합니다." + : error.code === "INVALID_PRICE" + ? "유효하지 않은 가격입니다." + : "거래 처리 중 오류가 발생했습니다.", + "error" + );Also applies to: 109-113
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (2)
public/images/login-guard.png
is excluded by!**/*.png
public/images/shield.png
is excluded by!**/*.png
📒 Files selected for processing (7)
src/api/transaction/index.ts
(1 hunks)src/app/search/[id]/_components/loading-spiner.tsx
(1 hunks)src/app/search/[id]/_components/transaction-form/edit-cancel/edit-table-body.tsx
(2 hunks)src/app/search/[id]/_components/transaction-form/edit-cancel/index.tsx
(7 hunks)src/app/search/[id]/_components/transaction-form/history.tsx
(1 hunks)src/app/search/[id]/_components/transaction-form/index.tsx
(2 hunks)src/app/search/[id]/_components/transaction-form/trade/index.tsx
(3 hunks)
🔇 Additional comments (5)
src/app/search/[id]/_components/loading-spiner.tsx (2)
1-5
: 인터페이스 설계가 잘 되었습니다!
LoadingSpinnerProps
인터페이스를 통해 타입 안정성을 확보하고, 선택적 className
속성으로 유연한 스타일링이 가능하도록 구현되었습니다.
6-11
: 컴포넌트 구현이 깔끔합니다!
cn
유틸리티를 활용하여 기본 스타일과 사용자 정의 스타일을 효과적으로 결합하였습니다.
src/app/search/[id]/_components/transaction-form/history.tsx (1)
25-27
: 로딩 상태 처리가 잘 구현되었습니다!
isLoading
과 isPending
상태를 적절히 활용하여 사용자 경험을 개선하였습니다.
src/app/search/[id]/_components/transaction-form/trade/index.tsx (2)
18-18
: 토스트 알림 기능이 적절하게 통합되었습니다.
사용자 피드백을 위한 토스트 기능이 깔끔하게 구현되었습니다.
Also applies to: 46-46
Line range hint 1-270
: 컴포넌트 정리(cleanup) 로직 확인이 필요합니다.
mutation 구독과 관련된 부작용(side effects)이 적절히 정리되는지 확인이 필요합니다.
onError: (error) => { | ||
showToast(error.message, "error"); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
에러 메시지 처리 방식 개선이 필요합니다.
현재 에러 메시지를 직접 표시하고 있는데, 사용자 친화적인 에러 메시지로 변환하는 것이 좋겠습니다.
onError: (error) => {
- showToast(error.message, "error");
+ const userFriendlyMessage = error.message === "Failed to fetch stocks"
+ ? "거래 정보를 불러오는데 실패했습니다. 잠시 후 다시 시도해주세요."
+ : "요청 처리 중 오류가 발생했습니다.";
+ showToast(userFriendlyMessage, "error");
},
Also applies to: 88-90
[...limitOrderData] | ||
.sort((a, b) => b.OrderId - a.OrderId) | ||
.map((data) => ( | ||
<EditTableBody | ||
key={data.OrderId} | ||
data={data} | ||
isChecked={selectedOrders.includes(data.OrderId.toString())} | ||
toggleSelection={toggleOrderSelection} | ||
/> | ||
)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
성능 최적화가 필요합니다.
데이터 정렬 로직이 렌더링마다 실행되고 있습니다. useMemo를 사용하여 최적화하는 것이 좋겠습니다.
+ const sortedLimitOrderData = useMemo(
+ () =>
+ limitOrderData
+ ? [...limitOrderData].sort((a, b) => b.OrderId - a.OrderId)
+ : [],
+ [limitOrderData]
+ );
- [...limitOrderData]
- .sort((a, b) => b.OrderId - a.OrderId)
- .map((data) => (
+ sortedLimitOrderData.map((data) => (
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
[...limitOrderData] | |
.sort((a, b) => b.OrderId - a.OrderId) | |
.map((data) => ( | |
<EditTableBody | |
key={data.OrderId} | |
data={data} | |
isChecked={selectedOrders.includes(data.OrderId.toString())} | |
toggleSelection={toggleOrderSelection} | |
/> | |
)) | |
const sortedLimitOrderData = useMemo( | |
() => | |
limitOrderData | |
? [...limitOrderData].sort((a, b) => b.OrderId - a.OrderId) | |
: [], | |
[limitOrderData] | |
); | |
sortedLimitOrderData.map((data) => ( | |
<EditTableBody | |
key={data.OrderId} | |
data={data} | |
isChecked={selectedOrders.includes(data.OrderId.toString())} | |
toggleSelection={toggleOrderSelection} | |
/> | |
)) |
const { mutate: buyAtLimitPriceMutate } = useMutation({ | ||
mutationFn: buyAtLimitPrice, | ||
onSuccess: () => { | ||
setActiveTab("history"); | ||
setActiveTab("edit-cancel"); | ||
queryClient.invalidateQueries({ queryKey: ["limitOrder"] }); | ||
showToast("지정가로 매수가 완료되었습니다.", "success"); | ||
}, | ||
onError: (error) => { | ||
showToast(error.message, "error"); | ||
}, | ||
}); | ||
|
||
const { mutate: sellAtLimitPriceMutate } = useMutation({ | ||
mutationFn: sellAtLimitPrice, | ||
onSuccess: () => { | ||
setActiveTab("history"); | ||
setActiveTab("edit-cancel"); | ||
queryClient.invalidateQueries({ queryKey: ["limitOrder"] }); | ||
showToast("지정가로 매도가 완료되었습니다.", "success"); | ||
}, | ||
onError: (error) => { | ||
showToast(error.message, "error"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
로딩 상태 처리를 추가하면 좋겠습니다.
현재 거래 처리 중에 사용자에게 로딩 상태를 표시하지 않고 있습니다. 이는 사용자 경험을 저하시킬 수 있습니다.
+ const [isLoading, setIsLoading] = useState(false);
const { mutate: buyAtLimitPriceMutate } = useMutation({
mutationFn: buyAtLimitPrice,
+ onMutate: () => {
+ setIsLoading(true);
+ },
onSuccess: () => {
setActiveTab("edit-cancel");
queryClient.invalidateQueries({ queryKey: ["limitOrder"] });
showToast("지정가로 매수가 완료되었습니다.", "success");
+ setIsLoading(false);
},
onError: (error) => {
showToast(error.message, "error");
+ setIsLoading(false);
},
});
그리고 버튼 컴포넌트에 로딩 상태를 전달하여 시각적 피드백을 제공하세요:
<BuyFormButtons
orderType={type}
handleReset={handleReset}
handleSubmit={() => handleSubmit(handleConfirmPurchase)()}
+ isLoading={isLoading}
/>
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
src/app/search/[id]/_components/transaction-form/edit-cancel/index.tsx (1)
25-29
: 로딩 상태 처리가 개선되었습니다.
isLoading
과isPending
상태를 모두 확인하는 것은 좋은 방식입니다. 다만, 다음과 같은 최적화를 고려해보세요:- if (isLoading || isPending) { + const isLoadingState = isLoading || isPending; + if (isLoadingState) {이렇게 하면 조건문이 실행될 때마다 두 상태를 확인하지 않아도 됩니다.
Also applies to: 104-106
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
src/app/search/[id]/_components/transaction-form/edit-cancel/index.tsx
(7 hunks)src/components/common/button/index.tsx
(1 hunks)
🔇 Additional comments (3)
src/components/common/button/index.tsx (1)
34-34
: 디자인 시스템과의 일관성 확인이 필요합니다.
빨간색 버튼의 색상이 #E43851
에서 #F12E35
로 변경되었습니다. 이 변경사항이 디자인 시스템의 색상 팔레트와 일치하는지 확인해주세요.
✅ Verification successful
색상 변경이 디자인 시스템과 일치합니다.
검색 결과를 통해 #F12E35
색상이 프로젝트 전반에 걸쳐 일관되게 사용되고 있음을 확인했습니다. 이 색상은 아이콘, 버튼 등 주요 빨간색 요소에 사용되는 표준 색상으로 보입니다.
public/icons/high-graph.svg
와arrow-up.svg
에서 동일한#F12E35
색상 사용src/app/search/[id]/_components/transaction-form
의 거래 관련 컴포넌트에서 유사한 빨간색 계열 사용- 버튼 컴포넌트의 색상 변경이 전체 디자인 시스템의 색상 체계와 일치
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: 디자인 시스템에서 사용되는 다른 빨간색 색상 코드 검색
# 프로젝트 전체에서 hex 색상 코드 검색
rg -i '#[0-9a-f]{6}' --type css --type tsx
Length of output: 72
Script:
#!/bin/bash
# Description: 디자인 시스템에서 사용되는 다른 빨간색 색상 코드 검색
# TypeScript/React 파일에서 hex 색상 코드 검색
rg -t typescript -t tsx '#[0-9a-fA-F]{6}'
# CSS 파일에서도 hex 색상 코드 검색
rg -t css '#[0-9a-fA-F]{6}'
# 특별히 빨간색 계열(E와 F로 시작하는) 색상 코드 검색
rg -t typescript -t tsx -t css '#[EF][0-9a-fA-F]{5}'
Length of output: 300
Script:
#!/bin/bash
# 모든 파일에서 색상 코드 검색
rg '#[EF][0-9a-fA-F]{5}'
# 특정 파일 확장자를 지정하여 검색
find . -type f \( -name "*.tsx" -o -name "*.css" -o -name "*.ts" \) -exec rg -l '#[EF][0-9a-fA-F]{5}' {} \;
# tailwind 설정 파일 검색 및 내용 확인
find . -type f -name "tailwind.config.*" -exec cat {} \;
Length of output: 8128
src/app/search/[id]/_components/transaction-form/edit-cancel/index.tsx (2)
73-75
: 에러 메시지 처리 방식 개선이 필요합니다.
이전 리뷰에서 지적된 사용자 친화적인 에러 메시지 처리가 아직 적용되지 않았습니다.
Also applies to: 88-90
143-152
: 성능 최적화가 필요합니다.
렌더링마다 정렬 로직이 실행되는 문제가 아직 해결되지 않았습니다.
<Button | ||
variant="red" | ||
className="mr-10 w-120 text-black bg-[#0FED78] hover:bg-[#0FED78]/95" | ||
onClick={handleEdit} | ||
> | ||
정정 | ||
</Button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
버튼 스타일링에 일관성이 필요합니다.
variant="red"
로 설정되어 있지만, className
에서 초록색 배경을 덮어쓰고 있습니다. 이는 혼란을 야기할 수 있습니다.
다음과 같이 수정하는 것을 추천드립니다:
- <Button
- variant="red"
- className="mr-10 w-120 text-black bg-[#0FED78] hover:bg-[#0FED78]/95"
- onClick={handleEdit}
- >
+ <Button
+ variant="primary"
+ className="mr-10 w-120"
+ onClick={handleEdit}
+ >
Committable suggestion skipped: line range outside the PR's diff.
#️⃣ 이슈
📝 작업 내용
이번 PR에서 작업한 내용을 간략히 설명해주세요.
📸 스크린샷
✅ 체크 리스트
👩💻 공유 포인트 및 논의 사항
Summary by CodeRabbit
New Features
Bug Fixes
Documentation