supabase로 구현한 회원가입/로그인 기능에 아이디 찾기를 추가해보았다.
로그인 페이지와 별도로 페이지를 만들었다
//src>app>auth>find
"use client";
import React, { useState } from "react";
import FindID from "./FindID";
import FindPW from "./FindPW";
const AuthFindPage = () => {
const [mode, setMode] = useState<boolean>(true);
return <>{mode ? <FindID setMode={setMode} /> : <FindPW setMode={setMode} />}</>;
};
export default AuthFindPage;
FindId 컴포넌트가 아이디를 찾는 부분이다. 비밀번호 재설정도 추가할 예정.
//<FindId>
import React, { useState } from "react";
import PageBreadCrumb from "@/components/layout/PageBreadCrumb";
import { useForm, SubmitHandler } from "react-hook-form";
import { supabase } from "@/service/supabase";
import ResultID from "./ResultID";
interface Props {
setMode: React.Dispatch<React.SetStateAction<boolean>>;
}
interface FormValue {
name: string;
phone: string;
}
const linkList = [
...
];
const FindID = ({ setMode }: Props) => {
//찾기
const [find, setFind] = useState(false);
//찾기 결과
const [result, setResult] = useState<boolean | string>(false);
const {
register,
handleSubmit,
formState: { errors }
} = useForm<FormValue>({ mode: "onBlur" });
const onSubmit: SubmitHandler<FormValue> = async (inputData) => {
//아이디 찾기 버튼 눌렀을 때
setFind(true);
const { data, error } = await supabase
.from("userinfo")
.select("email")
.match({ username: inputData.name, phone: inputData.phone });
if (error) {
window.confirm("아이디 찾기 실패");
} else {
setResult(data[0]?.email || false);
}
};
return (
<>
<PageBreadCrumb linkList={linkList} />
<div className="flex justify-center items-center space-x-[40px] text-center text-[25px] font-semibold mb-[80px] ">
<h1>아이디 찾기</h1>
<p onClick={() => setMode(false)} className="text-tc-light cursor-pointer">
비밀번호 찾기
</p>
</div>
<div className="flex flex-col justify-center items-center ">
<div className="w-[345px]">
{!find ? (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-[15px]">
<label htmlFor="email" className="block mb-2">
Username
<span className="inline-block ml-2 text-[12px] text-red-600">{errors?.name?.message}</span>
</label>
<input
id="name"
type="text"
{...register("name", {
required: "이름을 입력하세요."
})}
placeholder="이름"
className="block w-full h-[50px] border p-[15px]"
/>
</div>
<div className="mb-[20px]">
<label htmlFor="phone" className="block mb-2">
Phone Number
<span className="inline-block ml-2 text-[12px] text-red-600">{errors?.phone?.message}</span>
</label>
<div className="grid grid-cols-5 w-full border">
<input
id="phone"
type="phone"
placeholder="휴대폰번호"
{...register("phone", {
required: "휴대폰번호를 입력하세요"
})}
className="block col-span-4 h-[50px] p-[15px]"
/>
<button className="border-l h-[50px] text-tc-middle font-normal">인증하기</button>
</div>
</div>
<button type="submit" className="h-[50px] rounded-[5px] w-[100%] bg-point text-white">
아이디 찾기
</button>
</form>
) : (
<ResultID result={result} setFind={setFind} setMode={setMode} />
)}
</div>
</div>
</>
);
};
export default FindID;
이름과 휴대폰번호를 입력받고 supabase userinfo 테이블에서 두 값을 같은 행의 id를 찾는다.
//아이디 찾기 버튼 눌렀을 때 setFind(true); const { data, error } = await supabase .from("userinfo") .select("email") .match({ username: inputData.name, phone: inputData.phone }); if (error) { window.confirm("아이디 찾기 실패"); } else { setResult(data[0]?.email || false); }
검색 결과에 맞춰 화면에 출력해준다.
//<ResultID>
import React from "react";
import { useRouter } from "next/navigation";
interface Props {
result: string | boolean;
setFind: React.Dispatch<React.SetStateAction<boolean>>;
setMode: React.Dispatch<React.SetStateAction<boolean>>;
}
const ResultID = ({ result, setFind, setMode }: Props) => {
const router = useRouter();
return (
<>
{result ? (
<div>
<p className="mb-[40px] text-center text-[18px] font-semibold">아이디 찾기가 완료되었습니다.</p>
<p className="px-[15px] py-[25px] mb-[20px] text-[16px] font-normal border">{result}</p>
<div className="flex justify-center space-x-[9px]">
<button
onClick={() => router.push("/auth")}
className="w-[168px] h-[50px] rounded-[5px] bg-point text-white"
>
로그인
</button>
<button
onClick={() => setMode(false)}
className="w-[168px] h-[50px] rounded-[5px] text-point border border-point"
>
비밀번호 찾기
</button>
</div>
</div>
) : (
<div>
<p className="mb-[40px] text-center text-[18px] font-semibold">고객님 명의로 찾은 아이디가 없습니다.</p>
<div className="flex justify-center space-x-[9px]">
<button onClick={() => setFind(false)} className="w-[168px] h-[50px] rounded-[5px] bg-point text-white">
다시 찾기
</button>
<button
onClick={() => router.push("/")}
className="w-[168px] h-[50px] rounded-[5px] text-point border border-point"
>
홈으로 이동
</button>
</div>
</div>
)}
</>
);
};
export default ResultID;