From 5f7ac9e13f2a0f7d3305e9d0f667955ab5155bc3 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 5 Aug 2024 18:27:25 +0900 Subject: [PATCH] =?UTF-8?q?[chore]=20=EB=A6=B0=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=ED=94=84=EB=A6=AC=ED=8B=B0=EC=96=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/AuthFirstSection.jsx | 151 ++++++++++++++++++++------------- src/auth/AuthModal.jsx | 45 ++++++---- src/auth/AuthSecondSection.jsx | 54 +++++++----- src/auth/InputWithTimer.jsx | 17 ++-- src/auth/mock.js | 24 ++++-- src/common/Button.jsx | 31 +++++-- src/common/Input.jsx | 22 +++-- src/common/PhoneInput.jsx | 32 ++++--- 8 files changed, 242 insertions(+), 134 deletions(-) diff --git a/src/auth/AuthFirstSection.jsx b/src/auth/AuthFirstSection.jsx index a2b33ba9..37063f62 100644 --- a/src/auth/AuthFirstSection.jsx +++ b/src/auth/AuthFirstSection.jsx @@ -4,67 +4,104 @@ import PhoneInput from "@/common/PhoneInput.jsx"; import Button from "@/common/Button.jsx"; import { fetchServer, HTTPError } from "@/common/fetchServer.js"; -function AuthFirstSection({name, setName, phone, setPhone, goNext}) -{ - const [errorMessage, setErrorMessage] = useState(""); +function AuthFirstSection({ name, setName, phone, setPhone, goNext }) { + const [errorMessage, setErrorMessage] = useState(""); - const checkboxStyle = `size-4 appearance-none + const checkboxStyle = `size-4 appearance-none border border-neutral-300 checked:bg-blue-400 checked:border-0 checked:bg-checked bg-center`; - async function onSubmit(e) - { - e.preventDefault(); - try { - const body = {name, phoneNumber: phone.replace(/\D+/g, "")}; - await fetchServer("/api/v1/event-user/send-auth", {method:"post", body}); - setErrorMessage(""); - goNext(); - } catch(e) { - if( e instanceof HTTPError ) { - if(e.status === 400) return setErrorMessage("잘못된 요청 형식입니다."); - if(e.status === 409) return setErrorMessage("등록된 참여자 정보가 있습니다."); - return setErrorMessage("서버와의 통신 중 오류가 발생했습니다."); - } - console.error(e); - setErrorMessage("알 수 없는 오류입니다. 프론트엔드 개발자에게 제보하세요."); - } - } + async function onSubmit(e) { + e.preventDefault(); + try { + const body = { name, phoneNumber: phone.replace(/\D+/g, "") }; + await fetchServer("/api/v1/event-user/send-auth", { + method: "post", + body, + }); + setErrorMessage(""); + goNext(); + } catch (e) { + if (e instanceof HTTPError) { + if (e.status === 400) return setErrorMessage("잘못된 요청 형식입니다."); + if (e.status === 409) + return setErrorMessage("등록된 참여자 정보가 있습니다."); + return setErrorMessage("서버와의 통신 중 오류가 발생했습니다."); + } + console.error(e); + setErrorMessage( + "알 수 없는 오류입니다. 프론트엔드 개발자에게 제보하세요.", + ); + } + } - return <> -

이벤트 응모를 위해
간단한 정보를 입력해주세요!

-
-
-
- - -
-
- - -
-
-
- - -
-
- + return ( + <> +

+ 이벤트 응모를 위해 +
+ 간단한 정보를 입력해주세요! +

+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + ); } -export default AuthFirstSection; \ No newline at end of file +export default AuthFirstSection; diff --git a/src/auth/AuthModal.jsx b/src/auth/AuthModal.jsx index 9f81d19b..4bbfde74 100644 --- a/src/auth/AuthModal.jsx +++ b/src/auth/AuthModal.jsx @@ -6,21 +6,36 @@ import { ModalCloseContext } from "@/modal/modal.jsx"; const AUTH_INPUT_PAGE = Symbol("input"); const AUTH_CODE_PAGE = Symbol("code"); -function AuthModal() -{ - const close = useContext(ModalCloseContext); - const [name, setName] = useState(""); - const [phone, setPhone] = useState(""); - const [page, setPage] = useState(AUTH_INPUT_PAGE); - const firstSectionProps = {name, setName, phone, setPhone, goNext: ()=>setPage(AUTH_CODE_PAGE)}; - const secondSectionProps = {name, phone}; +function AuthModal() { + const close = useContext(ModalCloseContext); + const [name, setName] = useState(""); + const [phone, setPhone] = useState(""); + const [page, setPage] = useState(AUTH_INPUT_PAGE); + const firstSectionProps = { + name, + setName, + phone, + setPhone, + goNext: () => setPage(AUTH_CODE_PAGE), + }; + const secondSectionProps = { name, phone }; - return
- {page === AUTH_CODE_PAGE ? : } - -
+ return ( +
+ {page === AUTH_CODE_PAGE ? ( + + ) : ( + + )} + +
+ ); } -export default AuthModal; \ No newline at end of file +export default AuthModal; diff --git a/src/auth/AuthSecondSection.jsx b/src/auth/AuthSecondSection.jsx index 18ced108..03a14408 100644 --- a/src/auth/AuthSecondSection.jsx +++ b/src/auth/AuthSecondSection.jsx @@ -2,25 +2,41 @@ import { useState } from "react"; import InputWithTimer from "./InputWithTimer.jsx"; import Button from "@/common/Button.jsx"; -function AuthSecondSection({name, phone}) -{ - const [ authNumber, setAuthNumber ] = useState(""); - const [ errorMessage, setErrorMessage ] = useState(""); +function AuthSecondSection({ phone }) { + const [authNumber, setAuthNumber] = useState(""); + //const [ errorMessage, setErrorMessage ] = useState(""); - const josa = "013678".includes(phone[phone.length - 1]) ? "으" : ""; - return <> -

{phone}{josa}로
인증번호를 전송했어요.

-
-
- - {errorMessage} -
-
- - -
-
- + const josa = "013678".includes(phone[phone.length - 1]) ? "으" : ""; + return ( + <> +

+ {phone} + {josa}로
+ 인증번호를 전송했어요. +

+
+
+ + + {"errorMessage"} + +
+
+ + +
+
+ + ); } -export default AuthSecondSection; \ No newline at end of file +export default AuthSecondSection; diff --git a/src/auth/InputWithTimer.jsx b/src/auth/InputWithTimer.jsx index 9851c09f..1c535af8 100644 --- a/src/auth/InputWithTimer.jsx +++ b/src/auth/InputWithTimer.jsx @@ -1,11 +1,14 @@ import Input from "@/common/Input.jsx"; -function InputWithTimer({text, setText, timer, ...otherProps}) -{ - return
- - 5:00 -
+function InputWithTimer({ text, setText, timer, ...otherProps }) { + return ( +
+ + + {timer} + +
+ ); } -export default InputWithTimer; \ No newline at end of file +export default InputWithTimer; diff --git a/src/auth/mock.js b/src/auth/mock.js index c4756a7a..425b25bd 100644 --- a/src/auth/mock.js +++ b/src/auth/mock.js @@ -1,13 +1,25 @@ import { http, HttpResponse } from "msw"; const handlers = [ - http.post("/api/v1/event-user/send-auth", async ({request}) => { - const {name, phoneNumber} = await request.json(); - if(phoneNumber === "01019991999") return HttpResponse.json({error:"중복된 사용자가 있음"}, {status: 409}); - if(name.length < 2) return HttpResponse.json({error:"응답 내용이 잘못됨"}, {status: 400}); - if(phoneNumber.length >= 12) return HttpResponse.json({error:"응답 내용이 잘못됨"}, {status: 400}); + http.post("/api/v1/event-user/send-auth", async ({ request }) => { + const { name, phoneNumber } = await request.json(); + if (phoneNumber === "01019991999") + return HttpResponse.json( + { error: "중복된 사용자가 있음" }, + { status: 409 }, + ); + if (name.length < 2) + return HttpResponse.json( + { error: "응답 내용이 잘못됨" }, + { status: 400 }, + ); + if (phoneNumber.length >= 12) + return HttpResponse.json( + { error: "응답 내용이 잘못됨" }, + { status: 400 }, + ); - return HttpResponse.json({return: true}); + return HttpResponse.json({ return: true }); }), ]; diff --git a/src/common/Button.jsx b/src/common/Button.jsx index 56019850..9cc56beb 100644 --- a/src/common/Button.jsx +++ b/src/common/Button.jsx @@ -1,20 +1,33 @@ -function Button({styleType, children, type="button", className, ...otherProps}) -{ - const isSubmit = !(type === "reset" || type === "button"); +function Button({ + styleType, + children, + type = "button", + className, + ...otherProps +}) { + const isSubmit = !(type === "reset" || type === "button"); - const filledStyle = `bg-black text-white active:bg-neutral-700 active:text-neutral-200 + const filledStyle = `bg-black text-white active:bg-neutral-700 active:text-neutral-200 hover:bg-neutral-700 disabled:bg-neutral-600 disabled:text-neutral-400 ${isSubmit ? "group-[:invalid]:bg-neutral-600 group-[:invalid]:text-neutral-400" : ""}`; - const ghostStyle = `bg-white text-black shadow-[0_0_0_2px_inset_currentColor] + const ghostStyle = `bg-white text-black shadow-[0_0_0_2px_inset_currentColor] active:bg-neutral-50 active:text-neutral-400 hover:bg-neutral-50 disabled:text-neutral-200 ${isSubmit ? "group-[:invalid]:text-neutral-200" : ""}`; - const defaultStyle = `px-6 py-4 text-body-m font-bold text-center + const defaultStyle = `px-6 py-4 text-body-m font-bold text-center disabled:cursor-default ${isSubmit ? "group-[:invalid]:cursor-default" : ""}`; - const typedStyle = styleType === "filled" ? filledStyle : ghostStyle; - return + const typedStyle = styleType === "filled" ? filledStyle : ghostStyle; + return ( + + ); } -export default Button; \ No newline at end of file +export default Button; diff --git a/src/common/Input.jsx b/src/common/Input.jsx index b5a64a5a..0869f5d0 100644 --- a/src/common/Input.jsx +++ b/src/common/Input.jsx @@ -1,16 +1,22 @@ -function Input({text, setText, isError, ...otherProps}) -{ - const inputboxStyle = `w-full h-14 p-4 bg-neutral-50 rounded text-body-m font-medium +function Input({ text, setText, isError, ...otherProps }) { + const inputboxStyle = `w-full h-14 p-4 bg-neutral-50 rounded text-body-m font-medium focus:bg-white focus:outline-neutral-800 placeholder:text-neutral-200`; - const errorStyle = `bg-white outline outline-red-500 focus:outline-red-500`; + const errorStyle = `bg-white outline outline-red-500 focus:outline-red-500`; - const errorInputStyle = `invalid:outline invalid:outline-red-500 + const errorInputStyle = `invalid:outline invalid:outline-red-500 invalid:focus:outline invalid:focus:outline-red-500`; - return setText(e.target.value)} {...otherProps} /> + return ( + setText(e.target.value)} + {...otherProps} + /> + ); } -export default Input; \ No newline at end of file +export default Input; diff --git a/src/common/PhoneInput.jsx b/src/common/PhoneInput.jsx index e932eef8..67dcd29b 100644 --- a/src/common/PhoneInput.jsx +++ b/src/common/PhoneInput.jsx @@ -1,18 +1,24 @@ import Input from "./Input.jsx"; -function PhoneInput({text, setText, ...otherProps}) -{ - function addHyphen(value) - { - const plain = value.replace(/\D/g, ""); +function PhoneInput({ text, setText, ...otherProps }) { + function addHyphen(value) { + const plain = value.replace(/\D/g, ""); - if(plain.length < 4) return plain; - if(plain.length <= 7) return plain.replace(/^(\d{3})(\d{0,4})$/, "$1-$2"); - if(plain.length <= 10) return plain.replace(/^(\d{3})(\d{3})(\d{0,4})$/, "$1-$2-$3"); - return plain.replace(/^(\d{3})(\d{4})(\d{4,})$/, "$1-$2-$3"); - } - return setText(addHyphen(value))} placeholder="-를 제외한 숫자를 입력하세요." - {...otherProps} maxLength="13"/> + if (plain.length < 4) return plain; + if (plain.length <= 7) return plain.replace(/^(\d{3})(\d{0,4})$/, "$1-$2"); + if (plain.length <= 10) + return plain.replace(/^(\d{3})(\d{3})(\d{0,4})$/, "$1-$2-$3"); + return plain.replace(/^(\d{3})(\d{4})(\d{4,})$/, "$1-$2-$3"); + } + return ( + setText(addHyphen(value))} + placeholder="-를 제외한 숫자를 입력하세요." + {...otherProps} + maxLength="13" + /> + ); } -export default PhoneInput; \ No newline at end of file +export default PhoneInput;