-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[#319] 판매글 작성 페이지 로직 커스텀 훅으로 정리
- Loading branch information
Showing
20 changed files
with
421 additions
and
215 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { useMutation } from "@tanstack/react-query"; | ||
import { useState } from "react"; | ||
import { useNavigate } from "react-router-dom"; | ||
|
||
import { postTransferItems } from "@/apis/postTransferItems"; | ||
import { PATH } from "@/constants/path"; | ||
import { useSelectedItemStore } from "@/store/store"; | ||
import { ProfileData } from "@/types/profile"; | ||
|
||
interface PostTransferItems { | ||
firstPrice: string; | ||
secondPrice: string; | ||
downTimeAfter: string; | ||
is2ndChecked: boolean; | ||
opt1: boolean; | ||
opt2: boolean; | ||
opt3: boolean; | ||
optFinal: boolean; | ||
bank: string | null; | ||
accountNumber: string | null; | ||
userData: ProfileData; | ||
} | ||
const usePostTransferItems = ({ | ||
firstPrice, | ||
secondPrice, | ||
downTimeAfter, | ||
is2ndChecked, | ||
opt1, | ||
opt2, | ||
opt3, | ||
optFinal, | ||
bank, | ||
accountNumber, | ||
userData, | ||
}: PostTransferItems) => { | ||
const selectedItem = useSelectedItemStore((state) => state.selectedItem); | ||
|
||
// 처음 들어올 때 계좌가 있는지 여부. | ||
const [firstlyNoAccount] = useState(userData?.accountNumber ? false : true); | ||
|
||
const navigate = useNavigate(); | ||
const { mutate } = useMutation({ | ||
mutationFn: () => | ||
postTransferItems({ | ||
pathVariable: `${selectedItem.reservationId}`, | ||
firstPrice: Number(firstPrice.split(",").join("")), | ||
secondPrice: Number(secondPrice.split(",").join("")), | ||
bank: bank as string, | ||
accountNumber: accountNumber as string, | ||
secondGrantPeriod: Number(downTimeAfter), | ||
isRegistered: is2ndChecked, | ||
standardTimeSellingPolicy: opt1, | ||
totalAmountPolicy: opt2, | ||
sellingModificationPolicy: opt3, | ||
productAgreement: optFinal, | ||
}), | ||
onSuccess: () => { | ||
alert("판매 게시물이 성공적으로 등록되었습니다!"); | ||
navigate(PATH.WRITE_TRANSFER_SUCCESS + "?FNA=" + `${firstlyNoAccount}`, { | ||
state: { bank, accountNumber }, | ||
}); | ||
}, | ||
}); | ||
|
||
return { mutate }; | ||
}; | ||
|
||
export default usePostTransferItems; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { useEffect, useState } from "react"; | ||
import { useNavigate } from "react-router-dom"; | ||
|
||
import { PATH } from "@/constants/path"; | ||
import { useSelectedItemStore, useStateHeaderStore } from "@/store/store"; | ||
|
||
interface changePageProps { | ||
is2ndChecked: boolean; | ||
firstCheckRef: React.MutableRefObject<null>; | ||
} | ||
|
||
const useChangePage = ({ is2ndChecked, firstCheckRef }: changePageProps) => { | ||
const navigate = useNavigate(); | ||
const setHeaderConfig = useStateHeaderStore((state) => state.setHeaderConfig); | ||
const selectedItem = useSelectedItemStore((state) => state.selectedItem); | ||
|
||
// 현재 페이지가 어디인지 | ||
const [accountSetting, setAccountSetting] = useState<"none" | "enter">( | ||
"none", | ||
); | ||
|
||
// 페이지 전환 시 적용할 효과 | ||
useEffect(() => { | ||
if (accountSetting === "none") { | ||
setHeaderConfig({ | ||
title: selectedItem.hotelName, | ||
undo: () => { | ||
navigate(PATH.WRITE_TRANSFER); | ||
}, | ||
}); | ||
|
||
if (is2ndChecked && firstCheckRef.current) { | ||
(firstCheckRef.current as HTMLInputElement).checked = true; | ||
} | ||
} | ||
|
||
if (accountSetting === "enter") { | ||
setHeaderConfig({ | ||
title: "계좌 연동하기", | ||
undo: () => { | ||
setAccountSetting("none"); | ||
}, | ||
}); | ||
|
||
if (is2ndChecked && firstCheckRef.current) { | ||
(firstCheckRef.current as HTMLInputElement).checked = false; | ||
} | ||
} | ||
// eslint-disable-next-line | ||
}, [accountSetting]); | ||
|
||
return { accountSetting, setAccountSetting }; | ||
}; | ||
|
||
export default useChangePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { useEffect } from "react"; | ||
|
||
import { ProfileData } from "@/types/profile"; | ||
|
||
interface ReadyToSubmitProps { | ||
setReadyToSubmit: React.Dispatch<React.SetStateAction<boolean>>; | ||
firstPrice: string; | ||
secondPrice: string; | ||
opt1: boolean; | ||
opt2: boolean; | ||
opt3: boolean; | ||
optFinal: boolean; | ||
bank: string | null; | ||
accountNumber: string | null; | ||
is2ndChecked: boolean; | ||
downTimeAfter: string; | ||
userData: ProfileData; | ||
} | ||
|
||
const useReadyToSubmit = ({ | ||
setReadyToSubmit, | ||
firstPrice, | ||
opt1, | ||
opt2, | ||
opt3, | ||
optFinal, | ||
bank, | ||
accountNumber, | ||
is2ndChecked, | ||
secondPrice, | ||
downTimeAfter, | ||
userData, | ||
}: ReadyToSubmitProps) => { | ||
useEffect(() => { | ||
setReadyToSubmit(() => { | ||
if ( | ||
firstPrice && | ||
opt1 && | ||
opt2 && | ||
opt3 && | ||
optFinal && | ||
bank && | ||
accountNumber | ||
) { | ||
// accountNumber 추가 | ||
if (!is2ndChecked) return true; // 2차 가격 설정하기 체크 안 하고 계좌 등록된 경우 | ||
|
||
if (is2ndChecked && secondPrice && downTimeAfter) { | ||
return true; // 2차 가격 설정한 경우 | ||
} else if (is2ndChecked && !secondPrice && !downTimeAfter) { | ||
return false; // 2차 가격 체크했지만 아무것도 쓰지 않은 경우는 일단 가능 | ||
} else if (is2ndChecked && !secondPrice && downTimeAfter) { | ||
return false; // 2차 가격 체크하고 2차 가격 입력 안 하고 시간만 입력한 경우 | ||
} else if (is2ndChecked && secondPrice && !downTimeAfter) { | ||
return false; // 2차 가격 체크하고 2차 시간 입력 안 하고 가격만 입력한 경우 | ||
} else if (!userData?.bank || !userData?.accountNumber) { | ||
return false; | ||
} | ||
} | ||
|
||
return false; // 1차가격 설정과 약관 동의 안한 경우 | ||
}); | ||
}, [ | ||
setReadyToSubmit, | ||
firstPrice, | ||
opt1, | ||
opt2, | ||
opt3, | ||
optFinal, | ||
is2ndChecked, | ||
secondPrice, | ||
downTimeAfter, | ||
userData, | ||
bank, | ||
accountNumber, | ||
]); | ||
}; | ||
|
||
export default useReadyToSubmit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import useToastConfig from "@/hooks/common/useToastConfig"; | ||
import { useSelectedItemStore } from "@/store/store"; | ||
import { ProfileData } from "@/types/profile"; | ||
|
||
interface SubmitProps { | ||
readyToSubmit: boolean; | ||
firstPrice: string; | ||
secondPrice: string; | ||
downTimeAfter: string; | ||
firstInputRef: React.MutableRefObject<null>; | ||
secondPriceInputRef: React.MutableRefObject<null>; | ||
secondTimeInputRef: React.MutableRefObject<null>; | ||
is2ndChecked: boolean; | ||
userData: ProfileData; | ||
mutate: () => void; | ||
opt1: boolean; | ||
opt2: boolean; | ||
opt3: boolean; | ||
optFinal: boolean; | ||
} | ||
|
||
const useSubmitHandler = ({ | ||
readyToSubmit, | ||
firstPrice, | ||
secondPrice, | ||
downTimeAfter, | ||
firstInputRef, | ||
secondPriceInputRef, | ||
secondTimeInputRef, | ||
is2ndChecked, | ||
userData, | ||
mutate, | ||
opt1, | ||
opt2, | ||
opt3, | ||
optFinal, | ||
}: SubmitProps) => { | ||
const { handleToast } = useToastConfig(); | ||
const selectedItem = useSelectedItemStore((state) => state.selectedItem); | ||
|
||
const submitHandler = () => { | ||
if (!readyToSubmit) { | ||
const firstPriceNum = Number(firstPrice.split(",").join("")); | ||
const secondPriceNum = Number(secondPrice.split(",").join("")); | ||
const downTimeAfterNum = Number(downTimeAfter); | ||
|
||
if (!firstPriceNum) { | ||
handleToast(true, [<>1차 가격을 설정해주세요</>]); | ||
if (firstInputRef.current) { | ||
(firstInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 1차 가격이 판매가보다 높을 때 | ||
} else if (firstPriceNum > selectedItem.purchasePrice) { | ||
handleToast(true, [ | ||
<>판매가격이 구매가보다 높아요! 판매가격을 확인해주세요</>, | ||
]); | ||
|
||
if (firstInputRef.current) { | ||
(firstInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 2차 가격이 1차 가격보다 높을 때 | ||
} else if (secondPriceNum > firstPriceNum) { | ||
handleToast(true, [<>2차가격은 1차 가격보다 낮게 설정해주세요</>]); | ||
|
||
if (secondPriceInputRef.current) { | ||
(secondPriceInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 2차가격 인하 시간을 3시간 이하로 설정했을 때 | ||
} else if (downTimeAfterNum && downTimeAfterNum < 3) { | ||
handleToast(true, [ | ||
<>체크인 3시간 전까지만 2차 가격 설정이 가능해요</>, | ||
]); | ||
|
||
if (secondTimeInputRef.current) { | ||
(secondTimeInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 2차 가격만 입력하고 2차 기준시간은 입력 안 했을 때 | ||
} else if (is2ndChecked && secondPrice && !downTimeAfter) { | ||
handleToast(true, [<>2차 가격으로 내릴 시간을 입력해주세요</>]); | ||
|
||
if (secondTimeInputRef.current) { | ||
(secondTimeInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 2차 기준시간만 입력하고 2차 가격은 입력 안 했을 때 | ||
} else if (is2ndChecked && !secondPrice && downTimeAfter) { | ||
handleToast(true, [<>2차 가격을 입력해주세요</>]); | ||
|
||
if (secondPriceInputRef.current) { | ||
(secondPriceInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
// 2차 가격 설정을 체크해놓고 2차 가격과 시간 모두 입력 안 했을 때 | ||
} else if (is2ndChecked && !secondPrice && !downTimeAfter) { | ||
handleToast(true, [<>2차 가격을 입력해주세요</>]); | ||
|
||
if (secondTimeInputRef.current) { | ||
(secondTimeInputRef.current as HTMLInputElement).focus(); | ||
// + 스크롤 상단으로 올리기 | ||
} | ||
} | ||
// 약관 동의를 다 안 했을 때 | ||
else if (!opt1 || !opt2 || !opt3 || !optFinal) { | ||
handleToast(true, [<>판매 진행 약관에 동의해주세요</>]); | ||
|
||
// 계좌를 입력 안 한 경우 | ||
} else if (!userData?.accountNumber) { | ||
handleToast(true, [<>계좌를 입력해주세요</>]); | ||
} | ||
|
||
return; | ||
} | ||
|
||
const confirmToProceed = confirm("판매 게시물을 등록하시겠어요?"); | ||
if (confirmToProceed) { | ||
mutate(); | ||
} | ||
}; | ||
|
||
return [submitHandler]; | ||
}; | ||
|
||
export default useSubmitHandler; |
Oops, something went wrong.