From 09f6f9d5faaeb03aaf694c6aacfc198bd1326579 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 13:52:41 +0000 Subject: [PATCH] Refactor Register page components Splits the Register page into smaller, more manageable components for better organization and maintainability. --- src/components/auth/LoginLink.tsx | 18 ++ src/components/auth/RegisterErrorDisplay.tsx | 18 ++ src/components/auth/RegisterForm.tsx | 191 ++++++++++++++++ src/components/auth/RegisterHeader.tsx | 13 ++ src/components/auth/ServerStatusAlert.tsx | 45 ++++ src/pages/Register.tsx | 216 +++---------------- 6 files changed, 309 insertions(+), 192 deletions(-) create mode 100644 src/components/auth/LoginLink.tsx create mode 100644 src/components/auth/RegisterErrorDisplay.tsx create mode 100644 src/components/auth/RegisterForm.tsx create mode 100644 src/components/auth/RegisterHeader.tsx create mode 100644 src/components/auth/ServerStatusAlert.tsx diff --git a/src/components/auth/LoginLink.tsx b/src/components/auth/LoginLink.tsx new file mode 100644 index 0000000..dea67aa --- /dev/null +++ b/src/components/auth/LoginLink.tsx @@ -0,0 +1,18 @@ + +import React from "react"; +import { Link } from "react-router-dom"; + +const LoginLink: React.FC = () => { + return ( +
+

+ 이미 계정이 있으신가요?{" "} + + 로그인 + +

+
+ ); +}; + +export default LoginLink; diff --git a/src/components/auth/RegisterErrorDisplay.tsx b/src/components/auth/RegisterErrorDisplay.tsx new file mode 100644 index 0000000..d6ef0b1 --- /dev/null +++ b/src/components/auth/RegisterErrorDisplay.tsx @@ -0,0 +1,18 @@ + +import React from "react"; + +interface RegisterErrorDisplayProps { + error: string | null; +} + +const RegisterErrorDisplay: React.FC = ({ error }) => { + if (!error) return null; + + return ( +
+

{error}

+
+ ); +}; + +export default RegisterErrorDisplay; diff --git a/src/components/auth/RegisterForm.tsx b/src/components/auth/RegisterForm.tsx new file mode 100644 index 0000000..ddb3b75 --- /dev/null +++ b/src/components/auth/RegisterForm.tsx @@ -0,0 +1,191 @@ + +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +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"; + +interface RegisterFormProps { + signUp: (email: string, password: string, username: string) => Promise<{ + error: any; + user: any; + }>; + serverStatus: { + checked: boolean; + connected: boolean; + message: string; + }; + setServerStatus: React.Dispatch< + React.SetStateAction<{ + checked: boolean; + connected: boolean; + message: string; + }> + >; + setRegisterError: React.Dispatch>; +} + +const RegisterForm: React.FC = ({ + signUp, + serverStatus, + setServerStatus, + setRegisterError, +}) => { + const [username, setUsername] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const { toast } = useToast(); + const navigate = useNavigate(); + + const handleRegister = async (e: React.FormEvent) => { + e.preventDefault(); + setRegisterError(null); + + // 서버 연결 상태 재확인 + if (!serverStatus.connected) { + const currentStatus = await verifyServerConnection(); + setServerStatus({ + checked: true, + connected: currentStatus.connected, + message: currentStatus.message + }); + + if (!currentStatus.connected) { + toast({ + title: "서버 연결 실패", + description: "서버에 연결할 수 없습니다. 네트워크 또는 서버 상태를 확인하세요.", + variant: "destructive" + }); + return; + } + } + + if (!username || !email || !password || !confirmPassword) { + toast({ + title: "입력 오류", + description: "모든 필드를 입력해주세요.", + variant: "destructive", + }); + return; + } + + if (password !== confirmPassword) { + toast({ + title: "비밀번호 불일치", + description: "비밀번호와 비밀번호 확인이 일치하지 않습니다.", + variant: "destructive", + }); + return; + } + + setIsLoading(true); + + try { + const { error, user } = await signUp(email, password, username); + + if (error) { + setRegisterError(error.message || '알 수 없는 오류가 발생했습니다.'); + } else if (user) { + // 회원가입 성공 시 로그인 페이지로 이동 + navigate("/login"); + } + } catch (error: any) { + console.error("회원가입 처리 중 예외 발생:", error); + setRegisterError(error.message || '예상치 못한 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }; + + return ( +
+
+
+
+ +
+ + setUsername(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ +
+ +
+ + setEmail(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ +
+ +
+ + setPassword(e.target.value)} + className="pl-10 neuro-pressed" + /> + +
+
+ +
+ +
+ + setConfirmPassword(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ + +
+
+
+ ); +}; + +export default RegisterForm; diff --git a/src/components/auth/RegisterHeader.tsx b/src/components/auth/RegisterHeader.tsx new file mode 100644 index 0000000..82e6485 --- /dev/null +++ b/src/components/auth/RegisterHeader.tsx @@ -0,0 +1,13 @@ + +import React from "react"; + +const RegisterHeader: React.FC = () => { + return ( +
+

젤리의 적자탈출

+

새 계정을 만들고 재정 관리를 시작하세요

+
+ ); +}; + +export default RegisterHeader; diff --git a/src/components/auth/ServerStatusAlert.tsx b/src/components/auth/ServerStatusAlert.tsx new file mode 100644 index 0000000..c8456ef --- /dev/null +++ b/src/components/auth/ServerStatusAlert.tsx @@ -0,0 +1,45 @@ + +import React from "react"; +import { RefreshCcw } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; + +interface ServerStatusAlertProps { + serverStatus: { + checked: boolean; + connected: boolean; + message: string; + }; + checkServerConnection: () => Promise; +} + +const ServerStatusAlert: React.FC = ({ + serverStatus, + checkServerConnection, +}) => { + if (!serverStatus.checked || serverStatus.connected) { + return null; + } + + return ( + + + 서버 연결 문제 + + + + {serverStatus.message} +

회원가입을 시도하기 전에 서버 연결 문제를 해결해주세요.

+
+
+ ); +}; + +export default ServerStatusAlert; diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index a6873a9..8c77d32 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -1,24 +1,20 @@ import React, { useState, useEffect } from "react"; -import { Link, useNavigate } from "react-router-dom"; -import { Label } from "@/components/ui/label"; -import { Input } from "@/components/ui/input"; -import { Button } from "@/components/ui/button"; -import { ArrowRight, Mail, KeyRound, User, Eye, EyeOff, RefreshCcw } from "lucide-react"; -import { useToast } from "@/hooks/useToast.wrapper"; +import { useNavigate } from "react-router-dom"; import { useAuth } from "@/contexts/auth"; +import { useToast } from "@/hooks/useToast.wrapper"; import { verifyServerConnection } from "@/contexts/auth/auth.utils"; + +// 분리된 컴포넌트들 임포트 +import RegisterHeader from "@/components/auth/RegisterHeader"; +import RegisterForm from "@/components/auth/RegisterForm"; +import LoginLink from "@/components/auth/LoginLink"; +import ServerStatusAlert from "@/components/auth/ServerStatusAlert"; import TestConnectionSection from "@/components/auth/TestConnectionSection"; import SupabaseConnectionStatus from "@/components/auth/SupabaseConnectionStatus"; -import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"; +import RegisterErrorDisplay from "@/components/auth/RegisterErrorDisplay"; const Register = () => { - const [username, setUsername] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [confirmPassword, setConfirmPassword] = useState(""); - const [showPassword, setShowPassword] = useState(false); - const [isLoading, setIsLoading] = useState(false); const [registerError, setRegisterError] = useState(null); const [testResults, setTestResults] = useState(null); const [serverStatus, setServerStatus] = useState<{ @@ -30,6 +26,7 @@ const Register = () => { connected: false, message: "서버 연결 상태를 확인 중입니다..." }); + const { toast } = useToast(); const navigate = useNavigate(); const { signUp, user } = useAuth(); @@ -73,192 +70,27 @@ const Register = () => { } }; - const handleRegister = async (e: React.FormEvent) => { - e.preventDefault(); - setRegisterError(null); - - // 서버 연결 상태 재확인 - if (!serverStatus.connected) { - const currentStatus = await verifyServerConnection(); - setServerStatus({ - checked: true, - connected: currentStatus.connected, - message: currentStatus.message - }); - - if (!currentStatus.connected) { - toast({ - title: "서버 연결 실패", - description: "서버에 연결할 수 없습니다. 네트워크 또는 서버 상태를 확인하세요.", - variant: "destructive" - }); - return; - } - } - - if (!username || !email || !password || !confirmPassword) { - toast({ - title: "입력 오류", - description: "모든 필드를 입력해주세요.", - variant: "destructive", - }); - return; - } - - if (password !== confirmPassword) { - toast({ - title: "비밀번호 불일치", - description: "비밀번호와 비밀번호 확인이 일치하지 않습니다.", - variant: "destructive", - }); - return; - } - - setIsLoading(true); - - try { - const { error, user } = await signUp(email, password, username); - - if (error) { - setRegisterError(error.message || '알 수 없는 오류가 발생했습니다.'); - } else if (user) { - // 회원가입 성공 시 로그인 페이지로 이동 - navigate("/login"); - } - } catch (error: any) { - console.error("회원가입 처리 중 예외 발생:", error); - setRegisterError(error.message || '예상치 못한 오류가 발생했습니다.'); - } finally { - setIsLoading(false); - } - }; - return (
-
-

젤리의 적자탈출

-

새 계정을 만들고 재정 관리를 시작하세요

-
+ - {/* 서버 연결 상태 알림 */} - {serverStatus.checked && !serverStatus.connected && ( - - - 서버 연결 문제 - - - - {serverStatus.message} -

회원가입을 시도하기 전에 서버 연결 문제를 해결해주세요.

-
-
- )} + -
-
-
-
- -
- - setUsername(e.target.value)} - className="pl-10 neuro-pressed" - /> -
-
- -
- -
- - setEmail(e.target.value)} - className="pl-10 neuro-pressed" - /> -
-
- -
- -
- - setPassword(e.target.value)} - className="pl-10 neuro-pressed" - /> - -
-
- -
- -
- - setConfirmPassword(e.target.value)} - className="pl-10 neuro-pressed" - /> -
-
- - {registerError && ( -
-

{registerError}

-
- )} - - -
-
-
+ -
-

- 이미 계정이 있으신가요?{" "} - - 로그인 - -

-
+ + + - {/* Supabase 연결 테스트 섹션 */}