/** * 안전한 Clerk useAuth 래퍼 * * Clerk이 비활성화된 상태에서도 안전하게 작동하도록 * Mock 데이터를 제공하는 useAuth 훅과 타입, 컴포넌트들 */ import { useAuth as useClerkAuth, useUser as useClerkUser, SignIn as ClerkSignIn, SignUp as ClerkSignUp, type User as ClerkUser, type Session as ClerkSession, } from "@clerk/clerk-react"; import { logger } from "@/utils/logger"; import React from "react"; // Clerk 비활성화 상태 확인 함수 const isClerkDisabled = (): boolean => { if (typeof window === "undefined") { return false; } const urlParams = new URLSearchParams(window.location.search); if (urlParams.get("noClerk") === "true") { return true; } if (sessionStorage.getItem("disableClerk") === "true") { return true; } if (sessionStorage.getItem("skipClerk") === "true") { return true; } if (sessionStorage.getItem("chunkLoadErrorMaxRetries") === "true") { return true; } return false; }; // Mock useAuth 반환값 const mockAuthData = { isLoaded: true, isSignedIn: false, userId: null, sessionId: null, user: null, getToken: () => Promise.resolve(null), signOut: () => Promise.resolve(), }; // Mock useUser 반환값 const mockUserData = { isLoaded: true, isSignedIn: false, user: null, }; /** * 안전한 useAuth 훅 * Clerk이 비활성화된 경우 Mock 데이터를 반환 */ export const useAuth = () => { // ESLint 규칙 비활성화: 이 함수는 특별한 경우로 조건부 훅 호출이 필요 if (isClerkDisabled()) { logger.debug("useAuth: Clerk 비활성화됨, Mock 데이터 반환"); return mockAuthData; } try { // eslint-disable-next-line react-hooks/rules-of-hooks const clerkAuth = useClerkAuth(); // Clerk 훅이 정상적으로 로드되지 않은 경우 if (!clerkAuth || !clerkAuth.isLoaded) { logger.debug("useAuth: Clerk 로딩 중 또는 오류, Mock 데이터 반환"); return mockAuthData; } return clerkAuth; } catch (error) { logger.warn("useAuth: Clerk 컨텍스트 오류, Mock 데이터로 폴백", error); // Clerk에 문제가 있으면 자동으로 비활성화 sessionStorage.setItem("disableClerk", "true"); return mockAuthData; } }; /** * 안전한 useUser 훅 * Clerk이 비활성화된 경우 Mock 데이터를 반환 */ export const useUser = () => { // ESLint 규칙 비활성화: 이 함수는 특별한 경우로 조건부 훅 호출이 필요 if (isClerkDisabled()) { logger.debug("useUser: Clerk 비활성화됨, Mock 데이터 반환"); return mockUserData; } try { // eslint-disable-next-line react-hooks/rules-of-hooks const clerkUser = useClerkUser(); // Clerk 훅이 정상적으로 로드되지 않은 경우 if (!clerkUser || !clerkUser.isLoaded) { logger.debug("useUser: Clerk 로딩 중 또는 오류, Mock 데이터 반환"); return mockUserData; } return clerkUser; } catch (error) { logger.warn("useUser: Clerk 컨텍스트 오류, Mock 데이터로 폴백", error); // Clerk에 문제가 있으면 자동으로 비활성화 sessionStorage.setItem("disableClerk", "true"); return mockUserData; } }; /** * Mock SignIn 컴포넌트 * Clerk이 비활성화된 경우 사용되는 대체 컴포넌트 */ const MockSignIn: React.FC> = (_props) => { return (

Zellyy Finance

개인 가계부 관리의 새로운 시작

🚧 인증 시스템이 일시적으로 비활성화되었습니다

개발 모드: 인증 없이 앱을 체험할 수 있습니다

); }; /** * Mock SignUp 컴포넌트 * Clerk이 비활성화된 경우 사용되는 대체 컴포넌트 */ const MockSignUp: React.FC> = (_props) => { return (

Zellyy Finance 시작하기

무료로 계정을 만들고 지출 관리를 시작하세요

🚧 인증 시스템이 일시적으로 비활성화되었습니다

개발 모드: 인증 없이 앱을 체험할 수 있습니다

); }; /** * 안전한 SignIn 컴포넌트 * Clerk이 비활성화된 경우 Mock 컴포넌트를 반환 */ export const SignIn: React.FC> = (props) => { if (isClerkDisabled()) { logger.debug("SignIn: Clerk 비활성화됨, Mock 컴포넌트 반환"); return ; } try { return ; } catch (error) { logger.warn("SignIn: Clerk Context 오류, Mock 컴포넌트로 폴백", error); sessionStorage.setItem("disableClerk", "true"); return ; } }; /** * 안전한 SignUp 컴포넌트 * Clerk이 비활성화된 경우 Mock 컴포넌트를 반환 */ export const SignUp: React.FC> = (props) => { if (isClerkDisabled()) { logger.debug("SignUp: Clerk 비활성화됨, Mock 컴포넌트 반환"); return ; } try { return ; } catch (error) { logger.warn("SignUp: Clerk Context 오류, Mock 컴포넌트로 폴백", error); sessionStorage.setItem("disableClerk", "true"); return ; } }; // 타입 다시 내보내기 export type User = ClerkUser; export type Session = ClerkSession; // 기본 내보내기 export default { useAuth, useUser, SignIn, SignUp };