-
Notifications
You must be signed in to change notification settings - Fork 1
refactor: 코드 분리 및 파일명 변경 #81
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import Button from "@/components/common/button"; | ||
| import { textMap } from "@/constants/trade"; | ||
| import cn from "@/utils/cn"; | ||
|
|
||
| import { TradeType } from "../../../types"; | ||
|
|
||
| interface FormButtonsProps { | ||
| orderType: TradeType; | ||
| handleReset: () => void; | ||
| handleSubmit: () => void; | ||
| } | ||
|
|
||
| export default function FormButtons({ | ||
| orderType, | ||
| handleReset, | ||
| handleSubmit, | ||
| }: FormButtonsProps) { | ||
| return ( | ||
| <div | ||
| className={cn( | ||
| "relative top-90 w-300", | ||
| orderType === TradeType.Edit && "top-110", | ||
| )} | ||
| > | ||
| <Button variant="outline-gray" onClick={handleReset}> | ||
| 초기화 | ||
| </Button> | ||
| <Button | ||
| variant="custom" | ||
| className={cn( | ||
| "ml-7 w-160", | ||
| orderType === TradeType.Buy && "bg-red-500 hover:bg-red-500/80", | ||
| orderType === TradeType.Sell && "bg-blue-500 hover:bg-blue-500/80", | ||
| orderType === TradeType.Edit && "bg-green-500 hover:bg-green-500/80", | ||
| )} | ||
| onClick={handleSubmit} | ||
| > | ||
| {textMap[orderType]} | ||
| </Button> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,200 @@ | ||||||||||||||
| "use client"; | ||||||||||||||
|
|
||||||||||||||
| import { zodResolver } from "@hookform/resolvers/zod"; | ||||||||||||||
| import { UseMutateFunction } from "@tanstack/react-query"; | ||||||||||||||
| import { useState } from "react"; | ||||||||||||||
| import { useForm } from "react-hook-form"; | ||||||||||||||
|
|
||||||||||||||
| import { colorMap } from "@/constants/trade"; | ||||||||||||||
| import { useStockInfoContext } from "@/context/stock-info-context"; | ||||||||||||||
| import { useAuth } from "@/hooks/use-auth"; | ||||||||||||||
| import { | ||||||||||||||
| LimitPriceOrderHistory, | ||||||||||||||
| ModifyTradeFormData, | ||||||||||||||
| } from "@/types/transaction"; | ||||||||||||||
| import { calculateTotalOrderAmount } from "@/utils/price"; | ||||||||||||||
| import { | ||||||||||||||
| BuyFormData, | ||||||||||||||
| BuyFormSchema, | ||||||||||||||
| } from "@/validation/schema/transaction-form"; | ||||||||||||||
|
|
||||||||||||||
| import useTradeMutations from "../../../hooks/use-trade-mutations"; | ||||||||||||||
| import { PriceType, TradeType } from "../../../types"; | ||||||||||||||
| import TradeTable from "../trade-table"; | ||||||||||||||
| import BuyableQuantity from "./buyable-quantity"; | ||||||||||||||
| import CurrentPrice from "./current-price"; | ||||||||||||||
| import FormButtons from "./form-buttons"; | ||||||||||||||
| import InputField from "./input-field"; | ||||||||||||||
| import PriceTypeDropdown from "./price-type-dropdown"; | ||||||||||||||
| import TotalAmount from "./total-amount"; | ||||||||||||||
|
|
||||||||||||||
| interface TradeProps { | ||||||||||||||
| type: TradeType; | ||||||||||||||
| defaultData?: LimitPriceOrderHistory; | ||||||||||||||
| handleMutate?: UseMutateFunction<string, Error, ModifyTradeFormData, unknown>; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| export default function BuyAndSell({ | ||||||||||||||
| type, | ||||||||||||||
| defaultData, | ||||||||||||||
| handleMutate, | ||||||||||||||
| }: TradeProps) { | ||||||||||||||
| const [priceType, setPriceType] = useState(PriceType.Limit); | ||||||||||||||
| const [isConfirmationPage, setIsConfirmationPage] = useState(false); | ||||||||||||||
|
|
||||||||||||||
| const { stockName, stockInfo } = useStockInfoContext(); | ||||||||||||||
| const { token } = useAuth(); | ||||||||||||||
| const trades = useTradeMutations(); | ||||||||||||||
|
|
||||||||||||||
| const { | ||||||||||||||
| control, | ||||||||||||||
| watch, | ||||||||||||||
| reset, | ||||||||||||||
| handleSubmit, | ||||||||||||||
| setValue, | ||||||||||||||
| formState: { errors }, | ||||||||||||||
| } = useForm<BuyFormData>({ | ||||||||||||||
| resolver: zodResolver(BuyFormSchema), | ||||||||||||||
| defaultValues: | ||||||||||||||
| type === TradeType.Edit && defaultData | ||||||||||||||
| ? { | ||||||||||||||
| count: defaultData.stockCount, | ||||||||||||||
| bidding: defaultData.buyPrice, | ||||||||||||||
| } | ||||||||||||||
| : { | ||||||||||||||
| count: undefined, | ||||||||||||||
| bidding: undefined, | ||||||||||||||
| }, | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| const watchedCount = watch("count"); | ||||||||||||||
| const watchedBidding = watch("bidding"); | ||||||||||||||
|
|
||||||||||||||
| const handleReset = () => { | ||||||||||||||
| reset({ | ||||||||||||||
| count: undefined, | ||||||||||||||
| bidding: undefined, | ||||||||||||||
| }); | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| const handlePriceTypeChange = (newPriceType: PriceType) => { | ||||||||||||||
| setPriceType(newPriceType); | ||||||||||||||
| setValue( | ||||||||||||||
| "bidding", | ||||||||||||||
| newPriceType === PriceType.Market ? Number(stockInfo.stockPrice) : 0, | ||||||||||||||
| ); | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| const handleConfirmPurchase = () => { | ||||||||||||||
| setIsConfirmationPage(true); | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| const transactionHandlers = { | ||||||||||||||
| [TradeType.Buy]: () => | ||||||||||||||
| priceType === PriceType.Market | ||||||||||||||
| ? trades.buyAtMarketPrice.mutate({ | ||||||||||||||
| token, | ||||||||||||||
| data: { stockName, quantity: watchedCount }, | ||||||||||||||
| }) | ||||||||||||||
| : trades.buyAtLimitPrice.mutate({ | ||||||||||||||
| token, | ||||||||||||||
| data: { | ||||||||||||||
| stockName, | ||||||||||||||
| limitPrice: watchedBidding, | ||||||||||||||
| quantity: watchedCount, | ||||||||||||||
| }, | ||||||||||||||
| }), | ||||||||||||||
|
|
||||||||||||||
| [TradeType.Sell]: () => | ||||||||||||||
| priceType === PriceType.Market | ||||||||||||||
| ? trades.sellAtMarketPrice.mutate({ | ||||||||||||||
| token, | ||||||||||||||
| data: { stockName, quantity: watchedCount }, | ||||||||||||||
| }) | ||||||||||||||
| : trades.sellAtLimitPrice.mutate({ | ||||||||||||||
| token, | ||||||||||||||
| data: { | ||||||||||||||
| stockName, | ||||||||||||||
| limitPrice: watchedBidding, | ||||||||||||||
| quantity: watchedCount, | ||||||||||||||
| }, | ||||||||||||||
| }), | ||||||||||||||
|
|
||||||||||||||
| [TradeType.Edit]: () => { | ||||||||||||||
| if (type !== TradeType.Edit || !handleMutate) return; | ||||||||||||||
| handleMutate({ | ||||||||||||||
| token, | ||||||||||||||
| orderId: defaultData?.OrderId, | ||||||||||||||
| data: { | ||||||||||||||
| stockName, | ||||||||||||||
| limitPrice: watchedBidding, | ||||||||||||||
| quantity: watchedCount, | ||||||||||||||
| }, | ||||||||||||||
| }); | ||||||||||||||
| }, | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| const handleConfirm = transactionHandlers[type]; | ||||||||||||||
|
|
||||||||||||||
| if (isConfirmationPage) { | ||||||||||||||
| return ( | ||||||||||||||
| <TradeTable | ||||||||||||||
| color={colorMap[type]} | ||||||||||||||
| submittedData={{ | ||||||||||||||
| stockName, | ||||||||||||||
| count: watchedCount, | ||||||||||||||
| bidding: watchedBidding, | ||||||||||||||
| totalAmount: calculateTotalOrderAmount(watchedCount, watchedBidding), | ||||||||||||||
| buyOrder: type === TradeType.Buy ? "매수" : "매도", | ||||||||||||||
| }} | ||||||||||||||
| onClickGoBack={() => setIsConfirmationPage(false)} | ||||||||||||||
| onClickConfirm={handleConfirm} | ||||||||||||||
| /> | ||||||||||||||
| ); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return ( | ||||||||||||||
| <div className="flex"> | ||||||||||||||
| <CurrentPrice /> | ||||||||||||||
| <form className="flex w-270 flex-col gap-16 pl-11"> | ||||||||||||||
| <PriceTypeDropdown | ||||||||||||||
| orderType={type} | ||||||||||||||
| priceType={priceType} | ||||||||||||||
| setPriceType={handlePriceTypeChange} | ||||||||||||||
| /> | ||||||||||||||
| <InputField | ||||||||||||||
| title="수량" | ||||||||||||||
| type="count" | ||||||||||||||
| placeholder="수량 입력" | ||||||||||||||
| inputSuffix="주" | ||||||||||||||
| state={watchedCount} | ||||||||||||||
| setState={setValue} | ||||||||||||||
| control={control} | ||||||||||||||
| errors={errors.count} | ||||||||||||||
| quantity={10} | ||||||||||||||
| /> | ||||||||||||||
|
|
||||||||||||||
| {type !== "edit" && ( | ||||||||||||||
| <BuyableQuantity bidding={watchedBidding} type={type} /> | ||||||||||||||
| )} | ||||||||||||||
|
Comment on lines
+177
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [타입 비교 시 Enum을 사용하도록 수정 필요] TradeType은 Enum으로 정의되어 있으므로, 문자열 리터럴 대신 Enum 값을 사용하여 비교하는 것이 좋습니다. 현재 코드에서는 수정 제안: - {type !== "edit" && (
+ {type !== TradeType.Edit && (📝 Committable suggestion
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| <InputField | ||||||||||||||
| title="호가" | ||||||||||||||
| type="bidding" | ||||||||||||||
| placeholder="호가 입력" | ||||||||||||||
| inputSuffix="원" | ||||||||||||||
| state={watchedBidding} | ||||||||||||||
| setState={setValue} | ||||||||||||||
| control={control} | ||||||||||||||
| errors={errors.bidding} | ||||||||||||||
| /> | ||||||||||||||
| <TotalAmount count={watchedCount} bidding={watchedBidding} /> | ||||||||||||||
| <FormButtons | ||||||||||||||
| orderType={type} | ||||||||||||||
| handleReset={handleReset} | ||||||||||||||
| handleSubmit={() => handleSubmit(handleConfirmPurchase)()} | ||||||||||||||
| /> | ||||||||||||||
| </form> | ||||||||||||||
| </div> | ||||||||||||||
| ); | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| import Dropdown from "@/components/common/dropdown"; | ||
|
|
||
| import { PriceType, TradeType } from "../../../types"; | ||
|
|
||
| interface PriceTypeDropdownProps { | ||
| orderType: "buy" | "sell" | "edit"; | ||
| priceType: string; | ||
| setPriceType: (value: string) => void; | ||
| orderType: TradeType; | ||
| priceType: PriceType; | ||
| setPriceType: (newPriceType: PriceType) => void; | ||
| } | ||
| export default function PriceTypeDropdown({ | ||
| orderType, | ||
|
|
@@ -12,14 +14,14 @@ export default function PriceTypeDropdown({ | |
| }: PriceTypeDropdownProps) { | ||
| return ( | ||
| <div className="flex gap-8"> | ||
| {orderType === "edit" ? ( | ||
| {orderType === TradeType.Edit ? ( | ||
| <span className="mb-4 grow rounded-2 border border-solid border-[#B6B6B6] p-13 text-left"> | ||
| 지정가 | ||
| </span> | ||
| ) : ( | ||
| <Dropdown | ||
| selectedValue={priceType} | ||
| onSelect={(value) => setPriceType(value as string)} | ||
| onSelect={(value) => setPriceType(value as PriceType)} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 타입 캐스팅 대신 제네릭 사용을 권장합니다.
<Dropdown<PriceType>
selectedValue={priceType}
onSelect={(value) => setPriceType(value)}
className="flex-1"
> |
||
| className="flex-1" | ||
| > | ||
| <Dropdown.Toggle>{priceType}</Dropdown.Toggle> | ||
|
|
||
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
[속성 명명 규칙 일관성 유지 필요]
TypeScript의 명명 규칙을 따르기 위해,
defaultData?.OrderId의OrderId를 소문자 카멜케이스인orderId로 변경하는 것이 좋습니다.수정 제안:
또한, 관련된 인터페이스나 타입 정의에서도 속성 이름을 일관성 있게 변경해야 합니다.