Migrate from Supabase to Appwrite with core functionality and UI components

This commit is contained in:
hansoo
2025-05-05 08:58:27 +09:00
parent fdfdf15166
commit f83bb384af
79 changed files with 2373 additions and 199 deletions

View File

@@ -0,0 +1,182 @@
import { useState, useEffect, useCallback } from 'react';
import { account } from '@/lib/appwrite';
import { ID } from 'appwrite';
// 인증 상태 인터페이스
interface AuthState {
user: any | null;
loading: boolean;
error: Error | null;
}
// 로그인 입력값 인터페이스
interface LoginCredentials {
email: string;
password: string;
}
// 회원가입 입력값 인터페이스
interface SignupCredentials extends LoginCredentials {
name?: string;
}
/**
* Appwrite 인증 관련 훅
* 로그인, 로그아웃, 회원가입 및 사용자 상태 관리
*/
export const useAppwriteAuth = () => {
// 인증 상태 관리
const [authState, setAuthState] = useState<AuthState>({
user: null,
loading: true,
error: null
});
// 컴포넌트 마운트 상태 추적
const [isMounted, setIsMounted] = useState(true);
// 사용자 정보 가져오기
const getCurrentUser = useCallback(async () => {
try {
const user = await account.get();
if (isMounted) {
setAuthState({
user,
loading: false,
error: null
});
}
return user;
} catch (error) {
if (isMounted) {
setAuthState({
user: null,
loading: false,
error: error as Error
});
}
return null;
}
}, [isMounted]);
// 이메일/비밀번호로 로그인
const login = useCallback(async ({ email, password }: LoginCredentials) => {
try {
setAuthState(prev => ({ ...prev, loading: true, error: null }));
// 비동기 작업 시작 전 UI 스레드 차단 방지
await new Promise(resolve => setTimeout(resolve, 0));
const session = await account.createEmailPasswordSession(email, password);
const user = await account.get();
if (isMounted) {
setAuthState({
user,
loading: false,
error: null
});
}
return { user, session };
} catch (error) {
if (isMounted) {
setAuthState(prev => ({
...prev,
loading: false,
error: error as Error
}));
}
throw error;
}
}, [isMounted]);
// 회원가입
const signup = useCallback(async ({ email, password, name }: SignupCredentials) => {
try {
setAuthState(prev => ({ ...prev, loading: true, error: null }));
// 비동기 작업 시작 전 UI 스레드 차단 방지
await new Promise(resolve => setTimeout(resolve, 0));
const user = await account.create(
ID.unique(),
email,
password,
name
);
// 회원가입 후 자동 로그인
await account.createEmailPasswordSession(email, password);
if (isMounted) {
setAuthState({
user,
loading: false,
error: null
});
}
return user;
} catch (error) {
if (isMounted) {
setAuthState(prev => ({
...prev,
loading: false,
error: error as Error
}));
}
throw error;
}
}, [isMounted]);
// 로그아웃
const logout = useCallback(async () => {
try {
setAuthState(prev => ({ ...prev, loading: true }));
// 현재 세션 삭제
await account.deleteSession('current');
if (isMounted) {
setAuthState({
user: null,
loading: false,
error: null
});
}
} catch (error) {
if (isMounted) {
setAuthState(prev => ({
...prev,
loading: false,
error: error as Error
}));
}
throw error;
}
}, [isMounted]);
// 초기 사용자 정보 로드
useEffect(() => {
setIsMounted(true);
getCurrentUser();
// 정리 함수
return () => {
setIsMounted(false);
};
}, [getCurrentUser]);
return {
user: authState.user,
loading: authState.loading,
error: authState.error,
login,
signup,
logout,
getCurrentUser
};
};
export default useAppwriteAuth;