From 624276df08e9cd3bc9d99b27130b6bcb5341b966 Mon Sep 17 00:00:00 2001 From: koreacomp5 Date: Fri, 10 Oct 2025 11:26:31 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B0=80=EC=9E=85=ED=8F=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/auth/register/route.ts | 7 +--- src/app/login/page.tsx | 3 ++ src/app/register/page.tsx | 60 ++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/app/register/page.tsx diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index 8471ca7..f35ab16 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -1,12 +1,7 @@ import { NextResponse } from "next/server"; import prisma from "@/lib/prisma"; import { registerSchema } from "@/lib/validation/auth"; -import { hash } from "crypto"; - -function hashPassword(pw: string) { - // 간이 해시(데모): 실제론 bcrypt/scrypt/argon2 사용 권장 - return hash("sha256", Buffer.from(pw)).digest("hex"); -} +import { hashPassword } from "@/lib/password"; export async function POST(req: Request) { const body = await req.json(); diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 32e03f8..7d81f7e 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -45,6 +45,9 @@ export default function LoginPage() { style={{ padding: 8, border: "1px solid #ddd", borderRadius: 6 }} /> +
+ 회원가입 +
); diff --git a/src/app/register/page.tsx b/src/app/register/page.tsx new file mode 100644 index 0000000..f39ab34 --- /dev/null +++ b/src/app/register/page.tsx @@ -0,0 +1,60 @@ +"use client"; +import React from "react"; +import { Button } from "@/app/components/ui/Button"; +import { useToast } from "@/app/components/ui/ToastProvider"; + +export default function RegisterPage() { + const { show } = useToast(); + const [form, setForm] = React.useState({ + nickname: "", + name: "", + phone: "", + birth: "", + password: "", + confirmPassword: "", + agreeTerms: false, + }); + const [loading, setLoading] = React.useState(false); + const onChange = (e: React.ChangeEvent) => { + const { name, value, type, checked } = e.target; + setForm((f) => ({ ...f, [name]: type === "checkbox" ? checked : value })); + }; + const onSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + try { + const res = await fetch("/api/auth/register", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(form), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data?.error || "회원가입 실패"); + show("회원가입 성공! 로그인해주세요"); + location.href = "/login"; + } catch (err: any) { + show(err.message || "회원가입 실패"); + } finally { + setLoading(false); + } + }; + return ( +
+

회원가입

+
+ + + + + + + + +
+
+ ); +} + +