Implement email verification on signup

The prompt requests to implement email verification logic during the signup process.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 16:11:04 +00:00
parent d3d746c9ef
commit 4d094fbaa8
2 changed files with 79 additions and 12 deletions

View File

@@ -1,3 +1,4 @@
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { Label } from "@/components/ui/label";
@@ -6,12 +7,15 @@ import { Button } from "@/components/ui/button";
import { ArrowRight, Mail, KeyRound, User, Eye, EyeOff } from "lucide-react";
import { useToast } from "@/hooks/useToast.wrapper";
import { verifyServerConnection } from "@/contexts/auth/auth.utils";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { InfoIcon } from "lucide-react";
interface RegisterFormProps {
signUp: (email: string, password: string, username: string) => Promise<{
error: any;
user: any;
redirectToSettings?: boolean;
emailConfirmationRequired?: boolean;
}>;
serverStatus: {
checked: boolean;
@@ -40,6 +44,7 @@ const RegisterForm: React.FC<RegisterFormProps> = ({
const [confirmPassword, setConfirmPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [emailConfirmationSent, setEmailConfirmationSent] = useState(false);
const { toast } = useToast();
const navigate = useNavigate();
@@ -119,7 +124,7 @@ const RegisterForm: React.FC<RegisterFormProps> = ({
try {
// 회원가입 시도
const { error, user, redirectToSettings } = await signUp(email, password, username);
const { error, user, redirectToSettings, emailConfirmationRequired } = await signUp(email, password, username);
if (error) {
// 오류 메시지 출력
@@ -164,14 +169,23 @@ const RegisterForm: React.FC<RegisterFormProps> = ({
});
}
} else if (user) {
// 회원가입 성공
toast({
title: "회원가입 성공",
description: "회원가입이 완료되었습니다. 로그인 페이지로 이동합니다.",
});
// 로그인 페이지로 이동
navigate("/login");
// 이메일 확인이 필요한 경우
if (emailConfirmationRequired) {
setEmailConfirmationSent(true);
toast({
title: "이메일 인증 필요",
description: `${email}로 인증 메일이 발송되었습니다. 메일함을 확인하고 인증을 완료해주세요.`,
});
} else {
// 이메일 확인이 필요하지 않은 경우 (자동 승인 등)
toast({
title: "회원가입 성공",
description: "회원가입이 완료되었습니다. 로그인 페이지로 이동합니다.",
});
// 로그인 페이지로 이동
navigate("/login");
}
}
} catch (error: any) {
console.error("회원가입 처리 중 예외 발생:", error);
@@ -187,6 +201,48 @@ const RegisterForm: React.FC<RegisterFormProps> = ({
}
};
// 이메일 인증 안내 화면 (인증 메일이 발송된 경우)
if (emailConfirmationSent) {
return (
<div className="neuro-flat p-8 mb-6">
<div className="text-center space-y-6">
<Mail className="w-16 h-16 mx-auto text-neuro-income" />
<h2 className="text-2xl font-bold"> </h2>
<p className="text-gray-600">
<strong>{email}</strong> .
.
</p>
<Alert className="bg-blue-50 border-blue-200 my-6">
<InfoIcon className="h-5 w-5 text-blue-600" />
<AlertTitle className="text-blue-700"> ?</AlertTitle>
<AlertDescription className="text-blue-600">
. .
</AlertDescription>
</Alert>
<div className="space-y-4 pt-4">
<Button
onClick={() => navigate("/login")}
variant="outline"
className="w-full"
>
</Button>
<Button
onClick={() => setEmailConfirmationSent(false)}
variant="ghost"
className="w-full"
>
</Button>
</div>
</div>
</div>
);
}
// 일반 회원가입 양식
return (
<div className="neuro-flat p-8 mb-6">
<form onSubmit={handleRegister}>
@@ -264,6 +320,15 @@ const RegisterForm: React.FC<RegisterFormProps> = ({
)}
</div>
<Alert className="bg-amber-50 border-amber-200">
<InfoIcon className="h-5 w-5 text-amber-600" />
<AlertTitle className="text-amber-700"> </AlertTitle>
<AlertDescription className="text-amber-600">
.
.
</AlertDescription>
</Alert>
<Button
type="submit"
className="w-full bg-neuro-income hover:bg-neuro-income/80 text-white py-6 h-auto"

View File

@@ -73,12 +73,13 @@ export const signUp = async (email: string, password: string, username: string)
// 회원가입 성공
if (data && data.user) {
// 이메일 확인이 필요한지 확인
const isEmailConfirmationRequired = data.user.identities &&
data.user.identities.length > 0 &&
!data.user.identities[0].identity_data?.email_verified;
if (isEmailConfirmationRequired) {
showAuthToast('회원가입 성공', '이메일 인증을 완료해주세요.', 'default');
showAuthToast('회원가입 성공', '이메일 인증을 완료해주세요. 인증 메일이 발송되었습니다.', 'default');
return {
error: null,
user: data.user,
@@ -93,11 +94,12 @@ export const signUp = async (email: string, password: string, username: string)
// 사용자 데이터가 없는 경우 (드물게 발생)
console.warn('회원가입 응답은 성공했지만 사용자 데이터가 없습니다');
showAuthToast('회원가입 성공', '계정이 생성되었습니다. 로그인해주세요.', 'default');
showAuthToast('회원가입 성공', '계정이 생성되었습니다. 이메일 인증을 완료한 후 로그인해주세요.', 'default');
return {
error: null,
user: { email },
message: '회원가입 완료'
message: '회원가입 완료',
emailConfirmationRequired: true
};
} catch (error: any) {
console.error('기본 회원가입 프로세스 예외:', error);