|
| 1 | +"use client" |
| 2 | + |
| 3 | +import { useState, useEffect } from "react"; |
| 4 | +import { useRouter } from "next/navigation"; |
| 5 | +import { Button } from "@nextui-org/react"; |
| 6 | + |
| 7 | +import ProfileInfoForm from "@/components/auth/signup/ProfileInfoForm"; |
| 8 | +import AdditionalInfoForm from "@/components/auth/signup/AdditionalInfoForm"; |
| 9 | + |
| 10 | +import { useAuthenticatedApi } from '@/hooks/useAuthenticatedApi.js'; |
| 11 | +import usePasswordValidation from "@/hooks/usePasswordValidation"; |
| 12 | + |
| 13 | +export default function Signup() { |
| 14 | + const router = useRouter(); |
| 15 | + const { apiClient, handLeLogout }= useAuthenticatedApi(); |
| 16 | + |
| 17 | + const [isLoading, setIsLoading] = useState(true); |
| 18 | + |
| 19 | + // 사용자 정보 상태 |
| 20 | + const [name, setName] = useState(""); |
| 21 | + const [email, setEmail] = useState(""); |
| 22 | + const [password, setPassword] = useState(""); |
| 23 | + const [confirmPassword, setConfirmPassword] = useState(""); |
| 24 | + const [isEmailValid, setIsEmailValid] = useState(false); |
| 25 | + const [major, setMajor] = useState(""); |
| 26 | + const [studentId, setStudentId] = useState(""); |
| 27 | + const [phoneNumber, setPhoneNumber] = useState(""); |
| 28 | + |
| 29 | + // 애니메이션 상태 |
| 30 | + const [isAnimating, setIsAnimating] = useState(false); |
| 31 | + const [isRendering, setIsRendering] = useState(false); |
| 32 | + |
| 33 | + // 필드 비활성화 상태 |
| 34 | + const [isNameDisabled, setIsNameDisabled] = useState(false); |
| 35 | + const [isEmailDisabled, setIsEmailDisabled] = useState(false); |
| 36 | + |
| 37 | + // 비밀번호 유효성 검사 훅 사용 |
| 38 | + const { errors } = usePasswordValidation(password); |
| 39 | + |
| 40 | + useEffect(() => { |
| 41 | + // localStorage에서 signup_email과 signup_name 값을 확인 |
| 42 | + if (typeof window !== 'undefined') { |
| 43 | + const storedEmail = localStorage.getItem('signup_email'); |
| 44 | + const storedName = localStorage.getItem('signup_name'); |
| 45 | + |
| 46 | + if (storedEmail) { |
| 47 | + setEmail(storedEmail); |
| 48 | + setIsEmailDisabled(true); |
| 49 | + } |
| 50 | + |
| 51 | + if (storedName) { |
| 52 | + setName(storedName); |
| 53 | + setIsNameDisabled(true); |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + setIsLoading(false); |
| 58 | + }, []); |
| 59 | + |
| 60 | + // 첫 번째 화면에서 다음 버튼 클릭 시 처리 |
| 61 | + const handleNext = () => { |
| 62 | + if (!name || !email || !password || !confirmPassword) { |
| 63 | + alert("모든 칸을 채워주세요."); |
| 64 | + return; |
| 65 | + } |
| 66 | + if (password !== confirmPassword) { |
| 67 | + alert("비밀번호가 일치하지 않습니다."); |
| 68 | + return; |
| 69 | + } |
| 70 | + if(email === "pwc2002"){ |
| 71 | + setIsEmailValid(true); |
| 72 | + alert("이미 가입된 이메일입니다."); |
| 73 | + return; |
| 74 | + } |
| 75 | + if(errors.length > 0){ |
| 76 | + alert("비밀번호 조건을 만족해주세요."); |
| 77 | + return; |
| 78 | + } |
| 79 | + |
| 80 | + // 화면 전환 애니메이션 |
| 81 | + setIsRendering(true); |
| 82 | + setTimeout(() => { |
| 83 | + setIsAnimating(true); |
| 84 | + }, 100); |
| 85 | + }; |
| 86 | + |
| 87 | + const setMajorInfo = (value) => { |
| 88 | + setMajor(value); |
| 89 | + }; |
| 90 | + |
| 91 | + // 가입하기 버튼 클릭 시 처리 |
| 92 | + const handleSignup = async () => { |
| 93 | + if (!major || !studentId || !phoneNumber) { |
| 94 | + alert("모든 칸을 채워주세요."); |
| 95 | + console.log(name,email,password,major,studentId,phoneNumber); |
| 96 | + return; |
| 97 | + } |
| 98 | + |
| 99 | + // 회원가입 정보 객체 생성 |
| 100 | + const userinfo = { |
| 101 | + name: name, |
| 102 | + email: email, |
| 103 | + password: password, |
| 104 | + major: major, |
| 105 | + studentId: studentId, |
| 106 | + phoneNumber: phoneNumber |
| 107 | + } |
| 108 | + |
| 109 | + try { |
| 110 | + const res = await apiClient.post('/auth/signup', userinfo); |
| 111 | + console.log(res); |
| 112 | + } catch (error) { |
| 113 | + console.log(error); |
| 114 | + } |
| 115 | + |
| 116 | + // 홈으로 리디렉션 |
| 117 | + router.push("/"); |
| 118 | + }; |
| 119 | + |
| 120 | + // 로딩 상태 처리 |
| 121 | + if (isLoading) { |
| 122 | + return ( |
| 123 | + <div className="flex flex-col w-full items-center justify-center h-screen bg-black"> |
| 124 | + <div className="text-white text-2xl">로딩 중...</div> |
| 125 | + </div> |
| 126 | + ); |
| 127 | + } |
| 128 | + |
| 129 | + return ( |
| 130 | + <div className="flex flex-col w-full items-center justify-start h-screen bg-black"> |
| 131 | + <div className="flex flex-col max-w-[414px] w-full h-full pt-[30px] px-5"> |
| 132 | + <p className="text-white text-xl font-bold mb-2">회원가입하기</p> |
| 133 | + |
| 134 | + <div className="relative w-full h-full overflow-y-scroll"> |
| 135 | + <div key="screen1" className={`absolute w-full transition-all duration-500 ease-in-out transform ${isAnimating ? "-translate-x-full opacity-0" : "translate-x-0 opacity-100"}`}> |
| 136 | + <ProfileInfoForm |
| 137 | + name={name} |
| 138 | + setName={setName} |
| 139 | + email={email} |
| 140 | + setEmail={setEmail} |
| 141 | + password={password} |
| 142 | + setPassword={setPassword} |
| 143 | + confirmPassword={confirmPassword} |
| 144 | + setConfirmPassword={setConfirmPassword} |
| 145 | + errors={errors} |
| 146 | + isEmailValid={isEmailValid} |
| 147 | + isNameDisabled={isNameDisabled} |
| 148 | + isEmailDisabled={isEmailDisabled} |
| 149 | + /> |
| 150 | + </div> |
| 151 | + |
| 152 | + <div key="screen2" className={`${isRendering ? "" : "hidden"} absolute w-full transition-all duration-500 ease-in-out transform ${isAnimating ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}`}> |
| 153 | + <AdditionalInfoForm |
| 154 | + major={major} |
| 155 | + setMajor={setMajorInfo} |
| 156 | + studentId={studentId} |
| 157 | + setStudentId={setStudentId} |
| 158 | + phoneNumber={phoneNumber} |
| 159 | + setPhoneNumber={setPhoneNumber} |
| 160 | + /> |
| 161 | + </div> |
| 162 | + </div> |
| 163 | + |
| 164 | + {/* 하단 버튼 영역 */} |
| 165 | + <div className="flex flex-col w-full pb-4 mt-auto"> |
| 166 | + <Button |
| 167 | + className="text-white bg-[#EA4336] w-full h-[48px] rounded-full" |
| 168 | + style={{boxShadow: "black 0px -10px 20px 10px"}} |
| 169 | + onPress={isAnimating ? handleSignup : handleNext} |
| 170 | + isDisabled={!isAnimating && (!name || !email || !password || !confirmPassword || errors.length > 0 || password !== confirmPassword)} |
| 171 | + > |
| 172 | + {isAnimating ? "가입하기" : "다음"} |
| 173 | + </Button> |
| 174 | + </div> |
| 175 | + </div> |
| 176 | + </div> |
| 177 | + ); |
| 178 | +} |
0 commit comments