From e6d723c206a5a70550a44e64b94e638563b3f358 Mon Sep 17 00:00:00 2001 From: ej070961 Date: Sun, 11 Aug 2024 12:40:02 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9E=90=EC=B2=AD=EB=85=84=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EC=8B=9C=20=EC=9D=B8=EC=A6=9D=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=20=EB=B0=98=EC=98=81=EB=90=98=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MyPage/CanaryModal.tsx | 534 +++++++++++++------------- 1 file changed, 265 insertions(+), 269 deletions(-) diff --git a/src/components/MyPage/CanaryModal.tsx b/src/components/MyPage/CanaryModal.tsx index 42e7349..71c1d64 100644 --- a/src/components/MyPage/CanaryModal.tsx +++ b/src/components/MyPage/CanaryModal.tsx @@ -8,299 +8,295 @@ import PostalCode from "./PostalCode"; import useAuthStore from "../../storage/useAuthStore"; import { getPresignedUrl, uploadImageToS3 } from "../../apis/file-upload"; import { postCanaryApply } from "../../apis/canary"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; export interface postCode { - address: string; - zonecode: number | string; - detailAddress?: string; + address: string; + zonecode: number | string; + detailAddress?: string; } // prop 타입 정의 interface CanaryModalProps { - onClick: () => void; + onClick: () => void; } const CanaryModal = ({ onClick }: CanaryModalProps) => { - const { userData } = useAuthStore.getState(); - const [success, setSuccess] = useState(false); - const [image, setImage] = useState(null); - const fileInputRef = useRef(null); - const accesstoken = useAuthStore((state) => state.accessToken)!; - const [birthData, setBirthData] = useState({ - year: "2000", - month: "1", - day: "1", - }); - const [applyData, setApplyData] = useState({ - userId: userData.id || 0, - name: userData.nickname || "", - phone: "", - birth: "", - gender: true, - address: "", - detailAddress: "", - zip: "" as number | string, - certificateFilePath: "", - latitude: 0, - longitude: 0, + const { userData } = useAuthStore.getState(); + const [success, setSuccess] = useState(false); + const [image, setImage] = useState(null); + const fileInputRef = useRef(null); + const accesstoken = useAuthStore((state) => state.accessToken)!; + const [birthData, setBirthData] = useState({ + year: "2000", + month: "1", + day: "1", + }); + const [applyData, setApplyData] = useState({ + userId: userData.id || 0, + name: userData.nickname || "", + phone: "", + birth: "", + gender: true, + address: "", + detailAddress: "", + zip: "" as number | string, + certificateFilePath: "", + latitude: 0, + longitude: 0, + }); + const handleApplyData = (value: any, field: any) => { + let formattedValue = value; + + // 필드에 따라 포맷팅 처리 + if (field === "phone") { + formattedValue = formatPhoneNumber(value); + } + + setApplyData({ + ...applyData, + [field]: formattedValue, }); - const handleApplyData = (value: any, field: any) => { - let formattedValue = value; + }; - // 필드에 따라 포맷팅 처리 - if (field === "phone") { - formattedValue = formatPhoneNumber(value); - } + const handleBirthData = useCallback( + (data: any, key: string) => { + setBirthData({ ...birthData, [key]: data }); + }, + [birthData] + ); - setApplyData({ - ...applyData, - [field]: formattedValue, - }); - }; + const handleAddressChange = (data: postCode) => { + setApplyData({ + ...applyData, + address: data.address, + detailAddress: data.detailAddress!, + zip: data.zonecode, + }); + }; - const handleBirthData = useCallback( - (data: any, key: string) => { - setBirthData({ ...birthData, [key]: data }); - }, - [birthData] - ); + const handleImageChange = useCallback( + (e: React.ChangeEvent) => { + const file = e.target.files ? e.target.files[0] : null; + if (file) { + setImage(file); + } + }, + [] + ); - const handleAddressChange = (data: postCode) => { - setApplyData({ - ...applyData, - address: data.address, - detailAddress: data.detailAddress!, - zip: data.zonecode, - }); - }; + const formatPhoneNumber = (value: any) => { + // 숫자만 남기기 + const numbersOnly = value.replace(/\D/g, ""); - const handleImageChange = useCallback( - (e: React.ChangeEvent) => { - const file = e.target.files ? e.target.files[0] : null; - if (file) { - setImage(file); - } - }, - [] - ); + // 3자리, 4자리, 4자리로 나누어 하이픈 추가 + let formattedNumber = numbersOnly; + if (numbersOnly.length > 3 && numbersOnly.length <= 7) { + formattedNumber = `${numbersOnly.slice(0, 3)}-${numbersOnly.slice(3)}`; + } else if (numbersOnly.length > 7) { + formattedNumber = `${numbersOnly.slice(0, 3)}-${numbersOnly.slice( + 3, + 7 + )}-${numbersOnly.slice(7, 11)}`; + } - const formatPhoneNumber = (value: any) => { - // 숫자만 남기기 - const numbersOnly = value.replace(/\D/g, ""); + return formattedNumber; + }; - // 3자리, 4자리, 4자리로 나누어 하이픈 추가 - let formattedNumber = numbersOnly; - if (numbersOnly.length > 3 && numbersOnly.length <= 7) { - formattedNumber = `${numbersOnly.slice(0, 3)}-${numbersOnly.slice( - 3 - )}`; - } else if (numbersOnly.length > 7) { - formattedNumber = `${numbersOnly.slice(0, 3)}-${numbersOnly.slice( - 3, - 7 - )}-${numbersOnly.slice(7, 11)}`; - } + const convertToISO = (year: number, month: number, day: number): string => { + const date = new Date(year, month - 1, day); + return date.toISOString(); + }; - return formattedNumber; - }; + // QueryClient 가져오기 + const queryClient = useQueryClient(); - const convertToISO = (year: number, month: number, day: number): string => { - const date = new Date(year, month - 1, day); - return date.toISOString(); - }; + // useMutation을 사용하여 데이터 제출 및 applyStatus를 갱신 + const mutation = useMutation({ + mutationFn: async () => { + const uploadApplyData = { ...applyData }; + if (image) { + const presignedData = await getPresignedUrl( + "canary-certificate", + image.name, + accesstoken + ); + const presignedUrl = presignedData.data.url; + const filePath = presignedData.data.filePath; + await uploadImageToS3(image, presignedUrl); + uploadApplyData.certificateFilePath = filePath; + } + if (applyData.userId) { + const { year, month, day } = birthData; + const birth = convertToISO(+year, +month, +day); + uploadApplyData.birth = birth; + return postCanaryApply(uploadApplyData, accesstoken); + } + }, + onSuccess: () => { + // postCanaryApply가 성공적으로 완료되었을 때 applyStatus 다시 가져오기 + queryClient.invalidateQueries({ + queryKey: ["getCanaryStatus", userData.id, accesstoken], + }); + setSuccess(true); + }, + onError: () => { + alert("제출에 실패했습니다."); + }, + }); - const onSubmit = useCallback(async () => { - const uploadApplyData = { ...applyData }; - if (image) { - const presignedData = await getPresignedUrl( - "canary-certificate", - image.name, - accesstoken - ); - const presignedUrl = presignedData.data.url; - const filePath = presignedData.data.filePath; - await uploadImageToS3(image, presignedUrl); - uploadApplyData.certificateFilePath = filePath; - } - if (applyData.userId) { - const { year, month, day } = birthData; - const birth = convertToISO(+year, +month, +day); - uploadApplyData.birth = birth; - const res = await postCanaryApply(uploadApplyData, accesstoken); - if (res ? res.success : false) { - setSuccess(true); - } else { - alert("제출에 실패했습니다."); - } - } - }, [accesstoken, applyData, image, birthData]); + // 제출 버튼 클릭 시 mutation 실행 + const onSubmit = useCallback(() => { + mutation.mutate(); + }, [mutation]); - console.log(applyData); + console.log(applyData); - return ( - { - onClick(); - }} + return ( + { + onClick(); + }} + > + {!success ? ( + { + e.stopPropagation(); + }} > - {!success ? ( - { - e.stopPropagation(); - }} - > - 자립준비청년 인증하기 -
-
-
- - 보호종료확인서 업로드 - - -
- - {image?.name || ""} -
-
-
-
-
- 휴대폰 번호 - - handleApplyData(e.target.value, "phone") - } - value={applyData.phone.toString()} - /> -
-
- - handleBirthData(e.target.value, "year") - } - /> - - handleBirthData(e.target.value, "month") - } - /> - - handleBirthData(e.target.value, "day") - } - /> -
-
- - handleApplyData( - e.target.value === "남성", - "gender" - ) - } - /> -
-
- -
-
-
-
- ) : ( - -
인증 서류를 제출했습니다.
-
- 자립준비청년 인증까지 영업일 기준 최대 10일 소요됩니다. -
-