Migrate from Supabase to Appwrite with core functionality and UI components
This commit is contained in:
182
src/hooks/auth/useAppwriteAuth.ts
Normal file
182
src/hooks/auth/useAppwriteAuth.ts
Normal 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;
|
||||
Reference in New Issue
Block a user