로그인, 회원가입, 인풋의 기본 템플릿을 정리합니다.
인풋
// Input.tsx
import { ComponentProps, useId } from "react";
type InputProps = {
label?: string;
required?: boolean;
type? : "text" | "password";
} & ComponentProps<"input">;
function Input({ label, required, id, type = "text", ...props }: InputProps) {
const inputUid = useId();
const inputId = id || inputUid;
return (
<div className="flex flex-col gap-y-1.5 [&+&]:mt-4">
{label && (
<label htmlFor={inputId} className="text-sm font-semibold">
<span>{label}</span>
{required && <span className="text-red-500">*</span>}
</label>
)}
<input
id={inputId}
name={inputId}
type={type}
{...props}
className="border border-gray-400 rounded px-4 py-2.5 focus:outline-none focus:border-gray-950 transition"
/>
</div>
);
}
export default Input;
로그인
// Login.tsx
"use client";
import supabaseClient from "@/supabase/supabaseClient";
import { useRouter } from "next/router";
import { ComponentProps } from "react";
import Input from "../_components/Input";
function LogInPage() {
const router = useRouter()
const handleSubmit: ComponentProps<"form">["onSubmit"] = async (e) => {
e.preventDefault();
const form = e.currentTarget;
const formData = new FormData(form);
const email = formData.get("email") as string;
const password = formData.get("password") as string;
if (!email || !password) return alert("빈 값이 없도록 해주세요");
if (/\s/.test(email) || /\s/.test(password))
return alert("공백을 포함할 수 없습니다!");
if (!emailRegex.test(email))
return alert("유효한 이메일 주소를 입력하세요!");
if (password.length < 4 || password.length > 15)
return alert("비밀번호는 4~15 글자로 해야합니다!");
const { data, error } = await supabaseClient.auth.signInWithPassword({
email,
password,
});
if (error) return alert(error.message);
if (data) return router.push("/");
};
return (
<>
<form
onSubmit={handleSubmit}
className="max-w-sm mx-auto flex flex-col gap-y-8">
<div>
<Input label="아이디" required id="email" />
<Input label="비밀번호" required id="password" type="password"/>
</div>
<button
className="w-full bg-blue-500 text-white p-2 rounded-md"
type="submit"
>로그인하기</button>
</form>
</>
);
}
export default LogInPage;
회원가입
// Signup.tsx
"use client";
import validateInputs from "@/app/utils/validateInput";
import supabaseClient from "@/supabase/supabaseClient";
import { ComponentProps } from "react";
import Input from "../_components/Input";
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
function SignUpPage() {
const handleSubmit: ComponentProps<"form">["onSubmit"] = async (e) => {
e.preventDefault();
const form = e.currentTarget;
const formData = new FormData(form);
const email = formData.get("email") as string;
const password = formData.get("password") as string;
const passwordCheck = formData.get("password-check") as string;
const nickname = formData.get("nickname") as string;
if (!email || !password || !passwordCheck || !nickname)
return alert("빈 값이 없도록 해주세요");
if (password !== passwordCheck) return alert("비밀번호가 일치하지 않습니다");
const hasWhiteSpace = validateInputs(
[email, password, passwordCheck, nickname]);
if (hasWhiteSpace) return alert("공백을 포함할 수 없습니다!");
if (!emailRegex.test(email)) alert("유효한 이메일 주소를 입력하세요!");
if (password.length < 4 || password.length > 15)
return alert("비밀번호는 4~15 글자로 해야합니다!");
if (nickname.length < 1 || nickname.length > 10)
return alert("닉네임은 1~10 글자로 해야합니다!");
if (password !== passwordCheck) return alert("비밀번호가 일치하지 않습니다.");
const { data, error } = await supabaseClient.auth.signUp({
email,
password,
options: {
data: {
display_name: nickname,
},
},
});
if (error) return alert(error.message);
console.dir(data);
};
return (
<form
onSubmit={handleSubmit}
className="max-w-sm mx-auto flex flex-col gap-y-8">
<div>
<Input label="아이디" required id="email" />
<Input label="비밀번호" required id="password" type="password" />
<Input label="비밀번호 확인"
required id="password-check" type="password" />
<Input label="닉네임" required id="nickname" />
</div>
<button
className="w-full bg-blue-500 text-white p-2 rounded-md"
type="submit"
>회원가입하기</button>
</form>
);
}
export default SignUpPage;
기타유용한 함수 등
// validateInputs.ts
const validateInputs = (inputs: string[]) =>
inputs.some((input) => /\s/.test(input));
export default validateInputs;
export const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
'react' 카테고리의 다른 글
[240709 TIL] JSX 밖에서 훅 사용 (0) | 2024.07.09 |
---|---|
[240708 TIL] Suspense Provider 분리사용 (0) | 2024.07.08 |
[240624 TIL] 네이버지도 Step by Step 3 (0) | 2024.06.24 |
[240623 WIL] 네이버지도 Step by Step 2 (0) | 2024.06.23 |
[240622 WIL 네이버지도 api Step by Step 1 (0) | 2024.06.22 |