Skip to content

Commit

Permalink
[chore] 린트 수정 및 프리티어 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
lybell-art committed Aug 5, 2024
1 parent 0ed6379 commit 5f7ac9e
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 134 deletions.
151 changes: 94 additions & 57 deletions src/auth/AuthFirstSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <>
<p className="text-body-l font-bold text-neutral-700">이벤트 응모를 위해<br/>간단한 정보를 입력해주세요!</p>
<form className="flex flex-col flex-grow w-[calc(100%+0.25rem)] -left-0.5 relative gap-4 pb-4 group" onSubmit={onSubmit}>
<div className="flex flex-col flex-grow gap-7 px-0.5 relative h-0 overflow-y-auto">
<div className="flex flex-col gap-6">
<label className="flex flex-col gap-3">
<span className="text-body-m font-bold">이름</span>
<Input text={name} setText={setName} placeholder="ex) 홍길동" required minLength="2"/>
</label>
<label className="flex flex-col gap-3">
<span className="text-body-m font-bold">전화번호</span>
<PhoneInput text={phone} setText={setPhone} required isError={errorMessage !== ""}/>
<p className="w-full h-4 text-detail-l text-red-500">{errorMessage}</p>
</label>
</div>
<div className="flex flex-col gap-4 text-detail-l">
<label className="flex gap-2 items-center">
<input type="checkbox" className={checkboxStyle} required/>
<span className="font-bold text-neutral-600">개인정보 수집 동의(필수)</span>
<span className="font-medium text-neutral-300">자세히 보기</span>
</label>
<label className="flex gap-2 items-center">
<input type="checkbox" className={checkboxStyle}/>
<span className="font-bold text-neutral-600">마케팅 수신 동의(선택)</span>
<span className="font-medium text-neutral-300">자세히 보기</span>
</label>
</div>
</div>
<div className="w-full flex justify-center relative">
<Button styleType="filled" type="submit" className="w-36 min-h-14">인증 요청하기</Button>
<button type="button" className="absolute top-[calc(100%+1.25rem)] text-detail-l font-medium text-neutral-300">이미 정보를 입력하신 적이 있으신가요?</button>
</div>
</form>
</>
return (
<>
<p className="text-body-l font-bold text-neutral-700">
이벤트 응모를 위해
<br />
간단한 정보를 입력해주세요!
</p>
<form
className="flex flex-col flex-grow w-[calc(100%+0.25rem)] -left-0.5 relative gap-4 pb-4 group"
onSubmit={onSubmit}
>
<div className="flex flex-col flex-grow gap-7 px-0.5 relative h-0 overflow-y-auto">
<div className="flex flex-col gap-6">
<label className="flex flex-col gap-3">
<span className="text-body-m font-bold">이름</span>
<Input
text={name}
setText={setName}
placeholder="ex) 홍길동"
required
minLength="2"
/>
</label>
<label className="flex flex-col gap-3">
<span className="text-body-m font-bold">전화번호</span>
<PhoneInput
text={phone}
setText={setPhone}
required
isError={errorMessage !== ""}
/>
<p className="w-full h-4 text-detail-l text-red-500">
{errorMessage}
</p>
</label>
</div>
<div className="flex flex-col gap-4 text-detail-l">
<label className="flex gap-2 items-center">
<input type="checkbox" className={checkboxStyle} required />
<span className="font-bold text-neutral-600">
개인정보 수집 동의(필수)
</span>
<span className="font-medium text-neutral-300">자세히 보기</span>
</label>
<label className="flex gap-2 items-center">
<input type="checkbox" className={checkboxStyle} />
<span className="font-bold text-neutral-600">
마케팅 수신 동의(선택)
</span>
<span className="font-medium text-neutral-300">자세히 보기</span>
</label>
</div>
</div>
<div className="w-full flex justify-center relative">
<Button styleType="filled" type="submit" className="w-36 min-h-14">
인증 요청하기
</Button>
<button
type="button"
className="absolute top-[calc(100%+1.25rem)] text-detail-l font-medium text-neutral-300"
>
이미 정보를 입력하신 적이 있으신가요?
</button>
</div>
</form>
</>
);
}

export default AuthFirstSection;
export default AuthFirstSection;
45 changes: 30 additions & 15 deletions src/auth/AuthModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <div className="w-[calc(100%-1rem)] max-w-[31.25rem] h-[calc(100svh-2rem)] max-h-[40.625rem] p-6 sm:p-10 py-10 shadow bg-white relative flex flex-col gap-14">
{page === AUTH_CODE_PAGE ? <AuthSecondSection {...secondSectionProps}/> : <AuthFirstSection {...firstSectionProps}/>}
<button className="absolute top-10 right-8" onClick={close} aria-label="닫기">
<img src="/icons/close.svg" alt="닫기" width="24" height="24" />
</button>
</div>
return (
<div className="w-[calc(100%-1rem)] max-w-[31.25rem] h-[calc(100svh-2rem)] max-h-[40.625rem] p-6 sm:p-10 py-10 shadow bg-white relative flex flex-col gap-14">
{page === AUTH_CODE_PAGE ? (
<AuthSecondSection {...secondSectionProps} />
) : (
<AuthFirstSection {...firstSectionProps} />
)}
<button
className="absolute top-10 right-8"
onClick={close}
aria-label="닫기"
>
<img src="/icons/close.svg" alt="닫기" width="24" height="24" />
</button>
</div>
);
}

export default AuthModal;
export default AuthModal;
54 changes: 35 additions & 19 deletions src/auth/AuthSecondSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <>
<p className="text-body-l font-bold text-neutral-700">{phone}{josa}<br/>인증번호를 전송했어요.</p>
<form className="flex flex-col flex-grow w-full relative pb-4 gap-4 group">
<div className="flex flex-col flex-grow justify-center items-center gap-7 px-0.5 relative h-0">
<InputWithTimer text={authNumber} setText={setAuthNumber} required placeholder="인증번호를 입력해주세요" />
<span className="absolute bottom-5 text-detail-l font-bold text-red-400">{errorMessage}</span>
</div>
<div className="w-full flex justify-center gap-5">
<Button styleType="filled" type="submit" className="w-36 min-h-14">인증 완료하기</Button>
<Button styleType="ghost" type="button" className="min-h-14">재전송</Button>
</div>
</form>
</>
const josa = "013678".includes(phone[phone.length - 1]) ? "으" : "";
return (
<>
<p className="text-body-l font-bold text-neutral-700">
{phone}
{josa}<br />
인증번호를 전송했어요.
</p>
<form className="flex flex-col flex-grow w-full relative pb-4 gap-4 group">
<div className="flex flex-col flex-grow justify-center items-center gap-7 px-0.5 relative h-0">
<InputWithTimer
text={authNumber}
setText={setAuthNumber}
required
placeholder="인증번호를 입력해주세요"
/>
<span className="absolute bottom-5 text-detail-l font-bold text-red-400">
{"errorMessage"}
</span>
</div>
<div className="w-full flex justify-center gap-5">
<Button styleType="filled" type="submit" className="w-36 min-h-14">
인증 완료하기
</Button>
<Button styleType="ghost" type="button" className="min-h-14">
재전송
</Button>
</div>
</form>
</>
);
}

export default AuthSecondSection;
export default AuthSecondSection;
17 changes: 10 additions & 7 deletions src/auth/InputWithTimer.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Input from "@/common/Input.jsx";

function InputWithTimer({text, setText, timer, ...otherProps})
{
return <div className="w-full flex items-center relative">
<Input text={text} setText={setText} {...otherProps}/>
<span className="absolute text-body-s text-red-400 font-bold right-4">5:00</span>
</div>
function InputWithTimer({ text, setText, timer, ...otherProps }) {
return (
<div className="w-full flex items-center relative">
<Input text={text} setText={setText} {...otherProps} />
<span className="absolute text-body-s text-red-400 font-bold right-4">
{timer}
</span>
</div>
);
}

export default InputWithTimer;
export default InputWithTimer;
24 changes: 18 additions & 6 deletions src/auth/mock.js
Original file line number Diff line number Diff line change
@@ -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 });
}),
];

Expand Down
31 changes: 22 additions & 9 deletions src/common/Button.jsx
Original file line number Diff line number Diff line change
@@ -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 <button className={`${defaultStyle} ${typedStyle} ${className}`} type={type} {...otherProps}>{children}</button>
const typedStyle = styleType === "filled" ? filledStyle : ghostStyle;
return (
<button
className={`${defaultStyle} ${typedStyle} ${className}`}
type={type}
{...otherProps}
>
{children}
</button>
);
}

export default Button;
export default Button;
Loading

0 comments on commit 5f7ac9e

Please sign in to comment.