From 9ab2bf722ad34de4d52347ec7f7e825783d484ac 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:11:33 +0000 Subject: [PATCH] Refactor useLogin hook Refactor the useLogin hook to separate login and table setup logic for better maintainability. --- src/hooks/useLogin.ts | 57 ++++++++------------------------ src/hooks/useTableSetup.ts | 47 ++++++++++++++++++++++++++ src/pages/Login.tsx | 2 ++ src/utils/auth/loginUtils.ts | 64 ++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 44 deletions(-) create mode 100644 src/hooks/useTableSetup.ts create mode 100644 src/utils/auth/loginUtils.ts diff --git a/src/hooks/useLogin.ts b/src/hooks/useLogin.ts index 81efeee..a35de71 100644 --- a/src/hooks/useLogin.ts +++ b/src/hooks/useLogin.ts @@ -3,7 +3,12 @@ import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useToast } from "@/hooks/useToast.wrapper"; import { useAuth } from "@/contexts/auth"; -import { createRequiredTables } from "@/lib/supabase/setup"; +import { useTableSetup } from "@/hooks/useTableSetup"; +import { + getLoginErrorMessage, + showLoginErrorToast, + isCorsOrJsonError +} from "@/utils/auth/loginUtils"; export function useLogin() { const [email, setEmail] = useState(""); @@ -11,10 +16,11 @@ export function useLogin() { const [showPassword, setShowPassword] = useState(false); const [isLoading, setIsLoading] = useState(false); const [loginError, setLoginError] = useState(null); - const [isSettingUpTables, setIsSettingUpTables] = useState(false); + const navigate = useNavigate(); const { toast } = useToast(); const { signIn } = useAuth(); + const { isSettingUpTables, setupTables } = useTableSetup(); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); @@ -36,50 +42,12 @@ export function useLogin() { if (error) { console.error("로그인 실패:", error); - let errorMessage = "로그인에 실패했습니다."; - - // Supabase 오류 메시지 처리 - if (error.message) { - if (error.message.includes("Invalid login credentials")) { - errorMessage = "이메일 또는 비밀번호가 올바르지 않습니다."; - } else if (error.message.includes("Email not confirmed")) { - errorMessage = "이메일 인증이 완료되지 않았습니다. 이메일을 확인해주세요."; - } else if (error.message.includes("JSON")) { - errorMessage = "서버 응답 오류: JSON 파싱 실패. 네트워크 연결이나 CORS 설정을 확인하세요."; - } else if (error.message.includes("CORS") || error.message.includes("프록시")) { - errorMessage = "CORS 오류: 프록시 설정을 확인하거나 다른 프록시를 시도해보세요."; - } else if (error.message.includes("fetch") || error.message.includes("네트워크")) { - errorMessage = "네트워크 오류: 서버 연결에 실패했습니다."; - } else { - errorMessage = `오류: ${error.message}`; - } - } - + const errorMessage = getLoginErrorMessage(error); setLoginError(errorMessage); - - toast({ - title: "로그인 실패", - description: errorMessage, - variant: "destructive" - }); + showLoginErrorToast(errorMessage); } else if (user) { // 로그인 성공 시 필요한 테이블 설정 - try { - setIsSettingUpTables(true); - const { success, message } = await createRequiredTables(); - - if (success) { - console.log("테이블 설정 성공:", message); - } else { - console.warn("테이블 설정 문제:", message); - // 테이블 설정 실패해도 로그인은 진행 - } - } catch (setupError) { - console.error("테이블 설정 중 오류:", setupError); - } finally { - setIsSettingUpTables(false); - } - + await setupTables(); navigate("/"); } else { // user가 없지만 error도 없는 경우 (드문 경우) @@ -117,6 +85,7 @@ export function useLogin() { isSettingUpTables, loginError, setLoginError, - handleLogin + handleLogin, + isCorsOrJsonError: (msg: string | null) => isCorsOrJsonError(msg) }; } diff --git a/src/hooks/useTableSetup.ts b/src/hooks/useTableSetup.ts new file mode 100644 index 0000000..64044b1 --- /dev/null +++ b/src/hooks/useTableSetup.ts @@ -0,0 +1,47 @@ + +import { useState } from "react"; +import { useToast } from "@/hooks/useToast.wrapper"; +import { createRequiredTables } from "@/lib/supabase/setup"; + +/** + * Supabase 테이블 설정을 처리하는 커스텀 훅 + */ +export function useTableSetup() { + const [isSettingUpTables, setIsSettingUpTables] = useState(false); + const { toast } = useToast(); + + /** + * 로그인 성공 후 필요한 테이블을 설정합니다. + */ + const setupTables = async (): Promise => { + try { + setIsSettingUpTables(true); + const { success, message } = await createRequiredTables(); + + if (success) { + console.log("테이블 설정 성공:", message); + return true; + } else { + console.warn("테이블 설정 문제:", message); + // 사용자에게 경고 표시 (선택적) + toast({ + title: "테이블 설정 문제", + description: "일부 테이블 설정에 문제가 있었지만, 기본 기능은 사용할 수 있습니다.", + variant: "default" + }); + // 테이블 설정 실패해도 로그인은 진행 + return false; + } + } catch (setupError) { + console.error("테이블 설정 중 오류:", setupError); + return false; + } finally { + setIsSettingUpTables(false); + } + }; + + return { + isSettingUpTables, + setupTables + }; +} diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 76ea8b5..7427f96 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -16,6 +16,7 @@ const Login = () => { showPassword, setShowPassword, isLoading, + isSettingUpTables, loginError, setLoginError, handleLogin @@ -48,6 +49,7 @@ const Login = () => { showPassword={showPassword} setShowPassword={setShowPassword} isLoading={isLoading} + isSettingUpTables={isSettingUpTables} loginError={loginError} handleLogin={handleLogin} /> diff --git a/src/utils/auth/loginUtils.ts b/src/utils/auth/loginUtils.ts new file mode 100644 index 0000000..59de43b --- /dev/null +++ b/src/utils/auth/loginUtils.ts @@ -0,0 +1,64 @@ + +import { toast } from "@/hooks/useToast.wrapper"; + +/** + * 로그인 오류 메시지를 처리하는 유틸리티 함수 + */ +export const getLoginErrorMessage = (error: any): string => { + let errorMessage = "로그인에 실패했습니다."; + + // Supabase 오류 메시지 처리 + if (error.message) { + if (error.message.includes("Invalid login credentials")) { + errorMessage = "이메일 또는 비밀번호가 올바르지 않습니다."; + } else if (error.message.includes("Email not confirmed")) { + errorMessage = "이메일 인증이 완료되지 않았습니다. 이메일을 확인해주세요."; + } else if (error.message.includes("JSON")) { + errorMessage = "서버 응답 오류: JSON 파싱 실패. 네트워크 연결이나 CORS 설정을 확인하세요."; + } else if (error.message.includes("CORS") || error.message.includes("프록시")) { + errorMessage = "CORS 오류: 프록시 설정을 확인하거나 다른 프록시를 시도해보세요."; + } else if (error.message.includes("fetch") || error.message.includes("네트워크")) { + errorMessage = "네트워크 오류: 서버 연결에 실패했습니다."; + } else { + errorMessage = `오류: ${error.message}`; + } + } + + return errorMessage; +}; + +/** + * 로그인 성공 시 사용자에게 알림을 표시합니다. + */ +export const showLoginSuccessToast = () => { + toast({ + title: "로그인 성공", + description: "환영합니다! 대시보드로 이동합니다.", + variant: "default" + }); +}; + +/** + * 로그인 오류 시 사용자에게 알림을 표시합니다. + */ +export const showLoginErrorToast = (errorMessage: string) => { + toast({ + title: "로그인 실패", + description: errorMessage, + variant: "destructive" + }); +}; + +/** + * CORS 또는 JSON 관련 오류인지 확인합니다. + */ +export const isCorsOrJsonError = (errorMessage: string | null): boolean => { + if (!errorMessage) return false; + + return ( + errorMessage.includes('JSON') || + errorMessage.includes('CORS') || + errorMessage.includes('프록시') || + errorMessage.includes('서버 응답') + ); +};