From 7f4bce2769f241b397b5a565c23312dfc4e301de Mon Sep 17 00:00:00 2001 From: Bumang-Cyber Date: Tue, 5 Mar 2024 05:40:05 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20useChangePage(=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=84=ED=99=98=20=EC=8B=9C=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EB=B0=95=EC=8A=A4=20=EB=B0=8F=20=ED=86=A0=EA=B8=80=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B3=B4=EC=A1=B4),=20useReacdyToSubmit(=EA=B0=81?= =?UTF-8?q?=EC=A2=85=20state=EC=9D=98=20=EB=B3=80=ED=99=94=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=9D=BC=20=EC=A0=9C=EC=B6=9C=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94=20=EB=90=A0=EC=A7=80=20=EC=95=88=20?= =?UTF-8?q?=EB=90=A0=EC=A7=80=20=EC=97=AC=EB=B6=80),=20useSubmitHandler(?= =?UTF-8?q?=EC=A0=9C=EC=B6=9C=20=EB=B2=84=ED=8A=BC=20=EB=88=8C=EB=A0=80?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=B5=9C=EC=A2=85=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=95=EC=B1=85=20=EA=B2=80=EC=82=AC=20=ED=9B=84?= =?UTF-8?q?=20mutate=EB=B0=9C=EC=83=9D=EC=8B=9C=ED=82=A4=EB=8A=94=20?= =?UTF-8?q?=ED=9B=85)=20=EB=93=B1=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/fetchMainItems.ts | 3 - src/hooks/api/usePostTransferItems.ts | 68 +++++ src/hooks/common/useAnimateCarousel.ts | 6 +- src/hooks/common/useChangePage.ts | 55 ++++ src/hooks/common/useReadyToSubmit.ts | 79 ++++++ src/hooks/common/useSubmitHandler.tsx | 127 +++++++++ src/pages/homePage/Home.tsx | 1 - .../homePage/itemCarousel/ItemCarousel.tsx | 3 +- .../TransferWritingPrice.tsx | 255 +++++------------- .../accountSection/AccountSection.tsx | 3 +- .../agreementSection/AgreementSection.tsx | 2 +- .../checkBox/CheckBoxSection.style.ts | 3 +- .../enterAccountInfo/EnterAccountInfo.tsx | 5 +- .../firstPriceTag/FirstPriceTag.tsx | 5 +- .../inputSection/InputSection.tsx | 3 +- .../paymentSection/PaymentSection.style.ts | 3 +- .../paymentSection/PaymentSection.tsx | 3 +- 17 files changed, 414 insertions(+), 210 deletions(-) create mode 100644 src/hooks/api/usePostTransferItems.ts create mode 100644 src/hooks/common/useChangePage.ts create mode 100644 src/hooks/common/useReadyToSubmit.ts create mode 100644 src/hooks/common/useSubmitHandler.tsx diff --git a/src/apis/fetchMainItems.ts b/src/apis/fetchMainItems.ts index 6a9ed966..d31313cd 100644 --- a/src/apis/fetchMainItems.ts +++ b/src/apis/fetchMainItems.ts @@ -14,10 +14,7 @@ export const fetchMainItem = async (): Promise< "?cityNames=서울&cityNames=강원&cityNames=부산&cityNames=제주&cityNames=경상&cityNames=전라", ); - console.log(data); - const { weekend, ...locale } = data.data; - console.log(locale, "locale"); const temp = weekend.content.length ? weekend.content : []; return [locale, temp]; diff --git a/src/hooks/api/usePostTransferItems.ts b/src/hooks/api/usePostTransferItems.ts new file mode 100644 index 00000000..2f31eb56 --- /dev/null +++ b/src/hooks/api/usePostTransferItems.ts @@ -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; diff --git a/src/hooks/common/useAnimateCarousel.ts b/src/hooks/common/useAnimateCarousel.ts index 2fe489f5..1917330b 100644 --- a/src/hooks/common/useAnimateCarousel.ts +++ b/src/hooks/common/useAnimateCarousel.ts @@ -7,7 +7,7 @@ interface CarouselProps { } const inrange = (v: number, min: number, max: number) => { - // v는 current number? + // v는 델타x if (v < min) return min; if (v > max) return max; return v; @@ -38,6 +38,7 @@ export const useAnimateCarousel = ({ const handleDragChange = (deltaX: number) => { setTransX(inrange(deltaX, -slideWidth, slideWidth)); + console.log(deltaX, "deltaX"); }; const handleDragEnd = (deltaX: number) => { @@ -68,6 +69,7 @@ export const useAnimateCarousel = ({ const handleTouchMove = (moveEvent: globalThis.TouchEvent) => { if (moveEvent.cancelable) moveEvent.preventDefault(); + console.log(moveEvent.touches, "moveEvent.touches"); const delta = moveEvent.touches[0].pageX - touchEvent.touches[0].pageX; handleDragChange(delta); }; @@ -94,6 +96,8 @@ export const useAnimateCarousel = ({ clickEvent.preventDefault(); const handleMouseMove = (moveEvent: MouseEvent) => { + console.log(moveEvent.pageX, "mouseEvent pageX"); + console.log(clickEvent.pageX, "clickevent pageX"); const deltaX = moveEvent.pageX - clickEvent.pageX; handleDragChange(deltaX); }; diff --git a/src/hooks/common/useChangePage.ts b/src/hooks/common/useChangePage.ts new file mode 100644 index 00000000..c5ddc3f4 --- /dev/null +++ b/src/hooks/common/useChangePage.ts @@ -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; +} + +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; diff --git a/src/hooks/common/useReadyToSubmit.ts b/src/hooks/common/useReadyToSubmit.ts new file mode 100644 index 00000000..2cefa886 --- /dev/null +++ b/src/hooks/common/useReadyToSubmit.ts @@ -0,0 +1,79 @@ +import { useEffect } from "react"; + +import { ProfileData } from "@/types/profile"; + +interface ReadyToSubmitProps { + setReadyToSubmit: React.Dispatch>; + 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; diff --git a/src/hooks/common/useSubmitHandler.tsx b/src/hooks/common/useSubmitHandler.tsx new file mode 100644 index 00000000..e3e9aa45 --- /dev/null +++ b/src/hooks/common/useSubmitHandler.tsx @@ -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; + secondPriceInputRef: React.MutableRefObject; + secondTimeInputRef: React.MutableRefObject; + 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; diff --git a/src/pages/homePage/Home.tsx b/src/pages/homePage/Home.tsx index f5f8d1f2..c8a86b35 100644 --- a/src/pages/homePage/Home.tsx +++ b/src/pages/homePage/Home.tsx @@ -42,7 +42,6 @@ const Home = () => { (v, i) => [i, v], ); const [weekendHotels] = useState(WeekendMapped); - console.log(weekendHotels, "weekendHotels"); return ( diff --git a/src/pages/homePage/itemCarousel/ItemCarousel.tsx b/src/pages/homePage/itemCarousel/ItemCarousel.tsx index c1373e39..c699a5df 100644 --- a/src/pages/homePage/itemCarousel/ItemCarousel.tsx +++ b/src/pages/homePage/itemCarousel/ItemCarousel.tsx @@ -1,7 +1,6 @@ import { useAnimateCarousel } from "@hooks/common/useAnimateCarousel"; import { useCarouselSize } from "@hooks/common/useCarouselSize"; - -import type { LocaleItem } from "@type/saleSection"; +import { type LocaleItem } from "@type/saleSection"; import { useEffect } from "react"; import * as S from "./ItemCarousel.style"; diff --git a/src/pages/transferWritingPricePage/TransferWritingPrice.tsx b/src/pages/transferWritingPricePage/TransferWritingPrice.tsx index 745988c8..38dd4536 100644 --- a/src/pages/transferWritingPricePage/TransferWritingPrice.tsx +++ b/src/pages/transferWritingPricePage/TransferWritingPrice.tsx @@ -1,9 +1,5 @@ -import { PATH } from "@constants/path"; import usePreventLeave from "@hooks/common/usePreventLeave"; -import useToastConfig from "@hooks/common/useToastConfig"; -import { useMutation, useSuspenseQuery } from "@tanstack/react-query"; import { useEffect, useRef, useState } from "react"; -import { useNavigate } from "react-router-dom"; import AccountSection from "./accountSection/AccountSection"; import AgreementSection from "./agreementSection/AgreementSection"; @@ -13,241 +9,114 @@ import PaymentSection from "./paymentSection/PaymentSection"; import SecondPriceTag from "./secondPriceTag/SecondPriceTag"; import * as S from "./TransferWritingPrice.style"; import TransferPricingHeader from "./transferWritingPriceHeader/TransferPricingHeaderTop"; +import usePostTransferItems from "../../hooks/api/usePostTransferItems"; +import useChangePage from "../../hooks/common/useChangePage"; +import useReadyToSubmit from "../../hooks/common/useReadyToSubmit"; +import useSubmitHandler from "../../hooks/common/useSubmitHandler"; -import { fetchUserInfo } from "@/apis/fetchUserInfo"; -import { postTransferItems } from "@/apis/postTransferItems"; -import { useSelectedItemStore, useStateHeaderStore } from "@/store/store"; +import { useUserInfoQuery } from "@/hooks/api/useUserInfoQuery"; +import { useSelectedItemStore } from "@/store/store"; const TransferWritingPrice = () => { - usePreventLeave(true); - const navigate = useNavigate(); + // 현재 선택된 숙박 const selectedItem = useSelectedItemStore((state) => state.selectedItem); - const setHeaderConfig = useStateHeaderStore((state) => state.setHeaderConfig); - const { handleToast } = useToastConfig(); - const { data: userData } = useSuspenseQuery({ - queryKey: ["UserInfo"], - queryFn: fetchUserInfo, - staleTime: 5000000, - }); + // 유저 정보 + const userInfoQuery = useUserInfoQuery(); + const { data: userData } = userInfoQuery; - // first price value + // 1차 가격 const [firstPrice, setFirstPrice] = useState(""); - const [is2ndChecked, setIs2ndChecked] = useState(false); // activating 2nd price value state + const [is2ndChecked, setIs2ndChecked] = useState(false); // 2차 가격 설정하기 체크 여부 + // 1차 가격 HTMLElement const firstCheckRef = useRef(null); // 2차 가격 체크박스 ref const firstInputRef = useRef(null); - // second price value + // 2차 가격 const [secondPrice, setSecondPrice] = useState(""); const [downTimeAfter, setDownTimeAfter] = useState(""); + // 2차 가격 HTMLElement const secondPriceInputRef = useRef(null); const secondTimeInputRef = useRef(null); - // Account setting Mode - const [accountSetting, setAccountSetting] = useState<"none" | "enter">( - "none", - ); const [bank, setBank] = useState(userData?.bank ?? null); const [accountNumber, setAccountNumber] = useState( userData?.accountNumber ?? null, ); - // Terms in second price Values + // 약관 동의 const [opt1, setOpt1] = useState(false); const [opt2, setOpt2] = useState(false); const [opt3, setOpt3] = useState(false); const [optFinal, setOptFinal] = useState(false); - // finally able to submit + // 제출 가능 여부 const [readyToSubmit, setReadyToSubmit] = useState(false); - // 처음 들어올 때 계좌가 있는지 여부. - // false : true여야 정상 작동함. - const [firstlyNoAccount] = useState(userData?.accountNumber ? false : true); - useEffect(() => { setBank(userData?.bank ?? null); setAccountNumber(userData?.accountNumber ?? null); }, [userData]); - 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; - } - } + // HOOKS + // 작성 중 나가면 경고하는 훅 + usePreventLeave(true); - return false; // 1차가격 설정과 약관 동의 안한 경우 - }); - }, [ + // state변화에 따라 제출 버튼을 활성화/비활성화 하는 훅 + useReadyToSubmit({ + setReadyToSubmit, firstPrice, opt1, opt2, opt3, optFinal, + bank, + accountNumber, is2ndChecked, secondPrice, downTimeAfter, userData, - bank, - accountNumber, - ]); - - // 페이지 전환 시 적용할 효과 - 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]); - - 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 }, - }); - }, }); - 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, [<>계좌를 입력해주세요]); - } + // 계좌 등록 페이지 <-> 판매글 작성 페이지 왔다갔다 할 때 + // state상태에 따라 체크박스나 토글 풀려있는거 복구하는 훅 + const { accountSetting, setAccountSetting } = useChangePage({ + is2ndChecked, + firstCheckRef, + }); - return; - } + // 판매글 작성 POST 리액트 쿼리 훅 + const { mutate } = usePostTransferItems({ + firstPrice, + secondPrice, + downTimeAfter, + is2ndChecked, + opt1, + opt2, + opt3, + optFinal, + bank, + accountNumber, + userData, + }); - const confirmToProceed = confirm("판매 게시물을 등록하시겠어요?"); - if (confirmToProceed) { - mutate(); - } - }; + // 정책들을 모두 검토하고 마지막에 usePostTransferItems API를 POST요청하는 훅 + const [submitHandler] = useSubmitHandler({ + readyToSubmit, + firstPrice, + secondPrice, + downTimeAfter, + firstInputRef, + secondPriceInputRef, + secondTimeInputRef, + is2ndChecked, + userData, + mutate, + opt1, + opt2, + opt3, + optFinal, + }); return ( diff --git a/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx b/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx index df2848e7..95697046 100644 --- a/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx +++ b/src/pages/transferWritingPricePage/accountSection/AccountSection.tsx @@ -1,6 +1,7 @@ -import type { ProfileData } from "@/types/profile"; import * as S from "./AccountSection.style"; +import type { ProfileData } from "@/types/profile"; + interface AccountProps { bank: string | null; accountNumber: string | null; diff --git a/src/pages/transferWritingPricePage/agreementSection/AgreementSection.tsx b/src/pages/transferWritingPricePage/agreementSection/AgreementSection.tsx index b487b307..303ac97b 100644 --- a/src/pages/transferWritingPricePage/agreementSection/AgreementSection.tsx +++ b/src/pages/transferWritingPricePage/agreementSection/AgreementSection.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from "react"; -import CheckBoxSection from "../checkBox/CheckBoxSection"; import * as S from "./AgreementSection.style"; +import CheckBoxSection from "../checkBox/CheckBoxSection"; interface AgreementProps { opt1: boolean; diff --git a/src/pages/transferWritingPricePage/checkBox/CheckBoxSection.style.ts b/src/pages/transferWritingPricePage/checkBox/CheckBoxSection.style.ts index 6333d0d4..0d8fffad 100644 --- a/src/pages/transferWritingPricePage/checkBox/CheckBoxSection.style.ts +++ b/src/pages/transferWritingPricePage/checkBox/CheckBoxSection.style.ts @@ -1,6 +1,7 @@ -import { ColorKeys, theme, TypoKeys } from "@/styles/theme"; import styled from "styled-components"; +import { ColorKeys, theme, TypoKeys } from "@/styles/theme"; + export const CheckContainer = styled.section` display: flex; gap: 8px; diff --git a/src/pages/transferWritingPricePage/enterAccountInfo/EnterAccountInfo.tsx b/src/pages/transferWritingPricePage/enterAccountInfo/EnterAccountInfo.tsx index 2a26aaa7..39e9af84 100644 --- a/src/pages/transferWritingPricePage/enterAccountInfo/EnterAccountInfo.tsx +++ b/src/pages/transferWritingPricePage/enterAccountInfo/EnterAccountInfo.tsx @@ -1,5 +1,3 @@ -import { BANK_LIST } from "@/constants/bank"; -import { PATH } from "@/constants/path"; import usePreventLeave from "@hooks/common/usePreventLeave"; import useToastConfig from "@hooks/common/useToastConfig"; import { Nullable } from "@type/nullable"; @@ -9,6 +7,9 @@ import { useLocation } from "react-router-dom"; import * as S from "./EnterAccountInfo.style"; +import { BANK_LIST } from "@/constants/bank"; +import { PATH } from "@/constants/path"; + const EnterAccountInfo = ({ bank, accountNumber, diff --git a/src/pages/transferWritingPricePage/firstPriceTag/FirstPriceTag.tsx b/src/pages/transferWritingPricePage/firstPriceTag/FirstPriceTag.tsx index 01e500b5..446b34cc 100644 --- a/src/pages/transferWritingPricePage/firstPriceTag/FirstPriceTag.tsx +++ b/src/pages/transferWritingPricePage/firstPriceTag/FirstPriceTag.tsx @@ -1,9 +1,10 @@ -import priceFormat from "@/utils/priceFormat"; import { useEffect } from "react"; + +import * as S from "./FirstPriceTag.style"; import CheckBoxSection from "../checkBox/CheckBoxSection"; import InputSection from "../inputSection/InputSection"; -import * as S from "./FirstPriceTag.style"; +import priceFormat from "@/utils/priceFormat"; interface PriceTagProps { checkRef: React.MutableRefObject; diff --git a/src/pages/transferWritingPricePage/inputSection/InputSection.tsx b/src/pages/transferWritingPricePage/inputSection/InputSection.tsx index 19e61b40..2a07b906 100644 --- a/src/pages/transferWritingPricePage/inputSection/InputSection.tsx +++ b/src/pages/transferWritingPricePage/inputSection/InputSection.tsx @@ -1,8 +1,9 @@ -import priceFormat from "@/utils/priceFormat"; import useToastConfig from "@hooks/common/useToastConfig"; import * as S from "./InputSection.style"; +import priceFormat from "@/utils/priceFormat"; + interface InputProps { inputPosition: "left" | "center" | "right"; inputRef?: React.MutableRefObject; diff --git a/src/pages/transferWritingPricePage/paymentSection/PaymentSection.style.ts b/src/pages/transferWritingPricePage/paymentSection/PaymentSection.style.ts index 0e51fcb5..49b046de 100644 --- a/src/pages/transferWritingPricePage/paymentSection/PaymentSection.style.ts +++ b/src/pages/transferWritingPricePage/paymentSection/PaymentSection.style.ts @@ -1,8 +1,9 @@ -import { theme } from "@/styles/theme"; import { motion } from "framer-motion"; import { PiCaretDownBold } from "react-icons/pi"; import styled from "styled-components"; +import { theme } from "@/styles/theme"; + export const Container = styled(motion.div)<{ $is2ndChecked: boolean }>` padding: 16px 20px; background-color: white; diff --git a/src/pages/transferWritingPricePage/paymentSection/PaymentSection.tsx b/src/pages/transferWritingPricePage/paymentSection/PaymentSection.tsx index 9dcdeffc..cf5bed58 100644 --- a/src/pages/transferWritingPricePage/paymentSection/PaymentSection.tsx +++ b/src/pages/transferWritingPricePage/paymentSection/PaymentSection.tsx @@ -1,9 +1,10 @@ -import priceFormat from "@/utils/priceFormat"; import { motion } from "framer-motion"; import { useEffect, useState } from "react"; import * as S from "./PaymentSection.style"; +import priceFormat from "@/utils/priceFormat"; + interface PaymentProps { price: string; is2ndChecked: boolean; From ac7eb55c60589ba3368f93eef1bc1e5d204df50d Mon Sep 17 00:00:00 2001 From: Bumang-Cyber Date: Thu, 7 Mar 2024 17:54:29 +0900 Subject: [PATCH 2/3] =?UTF-8?q?design:=20=EC=A3=BC=EB=A7=90=20=ED=8A=B9?= =?UTF-8?q?=EA=B0=80=20=EC=97=86=EC=96=B4=EC=84=9C=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?padding=20=EB=84=A3=EC=97=88=EB=8D=98=EA=B1=B0=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/logout.ts | 3 ++- src/components/Helmet/Helmet.tsx | 3 ++- src/pages/homePage/Home.style.ts | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/apis/logout.ts b/src/apis/logout.ts index 6a3ad07f..d2e4e034 100644 --- a/src/apis/logout.ts +++ b/src/apis/logout.ts @@ -1,6 +1,7 @@ -import { ACCESS_TOKEN, END_POINTS, REFRESH_TOKEN } from "@/constants/api"; import { axiosInstance } from "@apis/axiosInstance"; +import { ACCESS_TOKEN, END_POINTS, REFRESH_TOKEN } from "@/constants/api"; + export const logout = async () => { await axiosInstance.post(`${END_POINTS.USER_INFO}/logout`, { accessToken: localStorage.getItem(ACCESS_TOKEN), diff --git a/src/components/Helmet/Helmet.tsx b/src/components/Helmet/Helmet.tsx index 5db8bba2..7ff0dd7e 100644 --- a/src/components/Helmet/Helmet.tsx +++ b/src/components/Helmet/Helmet.tsx @@ -1,6 +1,7 @@ -import { PATH } from "@/constants/path"; import { Helmet } from "react-helmet-async"; +import { PATH } from "@/constants/path"; + export const HelmetTag = ({ text }: { text: string }) => { return ( diff --git a/src/pages/homePage/Home.style.ts b/src/pages/homePage/Home.style.ts index 89b7e50f..73506097 100644 --- a/src/pages/homePage/Home.style.ts +++ b/src/pages/homePage/Home.style.ts @@ -1,10 +1,10 @@ import styled from "styled-components"; -export const Container = styled.section` +export const Container = styled.section<{ weekLength: undefined | number }>` background-color: ${({ theme }) => theme.color.greyScale6}; padding-top: 80px; - padding-bottom: 200px; + padding-bottom: ${({ weekLength }) => weekLength && "200px"}; display: flex; flex-direction: column; align-items: center; From 610d0f9bd8b3011688fdf57c1e9d6887d9e00ce6 Mon Sep 17 00:00:00 2001 From: Bumang-Cyber Date: Thu, 7 Mar 2024 18:04:05 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20Home=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20=EB=A7=88=EC=A7=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/homePage/Home.style.ts | 4 ++-- src/pages/homePage/Home.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/homePage/Home.style.ts b/src/pages/homePage/Home.style.ts index 73506097..0846cd14 100644 --- a/src/pages/homePage/Home.style.ts +++ b/src/pages/homePage/Home.style.ts @@ -1,10 +1,10 @@ import styled from "styled-components"; -export const Container = styled.section<{ weekLength: undefined | number }>` +export const Container = styled.section<{ $weekLength: undefined | number }>` background-color: ${({ theme }) => theme.color.greyScale6}; padding-top: 80px; - padding-bottom: ${({ weekLength }) => weekLength && "200px"}; + padding-bottom: ${({ $weekLength }) => !$weekLength && "200px"}; display: flex; flex-direction: column; align-items: center; diff --git a/src/pages/homePage/Home.tsx b/src/pages/homePage/Home.tsx index c8a86b35..678ab259 100644 --- a/src/pages/homePage/Home.tsx +++ b/src/pages/homePage/Home.tsx @@ -44,7 +44,7 @@ const Home = () => { const [weekendHotels] = useState(WeekendMapped); return ( - +