124 lines
3.4 KiB
TypeScript
124 lines
3.4 KiB
TypeScript
import { useEffect, useState, useCallback } from 'react';
|
|
import {
|
|
FacebookLoginResponse,
|
|
FacebookLoginError,
|
|
FacebookUser,
|
|
FacebookSDKInitOptions
|
|
} from '@/types/facebook-login';
|
|
|
|
export interface UseFacebookLoginOptions extends FacebookSDKInitOptions {}
|
|
|
|
export const useFacebookLogin = (options: UseFacebookLoginOptions) => {
|
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
const [user, setUser] = useState<FacebookUser | null>(null);
|
|
|
|
const { appId, version = 'v18.0', cookie = true, xfbml = true, autoLogAppEvents = true } = options;
|
|
|
|
// Initialize Facebook SDK
|
|
useEffect(() => {
|
|
if (typeof window === 'undefined') return;
|
|
|
|
// Load Facebook SDK if not already loaded
|
|
if (!window.FB) {
|
|
const script = document.createElement('script');
|
|
script.src = `https://connect.facebook.net/en_US/sdk.js`;
|
|
script.async = true;
|
|
script.defer = true;
|
|
script.crossOrigin = 'anonymous';
|
|
|
|
window.fbAsyncInit = () => {
|
|
window.FB.init({
|
|
appId,
|
|
cookie,
|
|
xfbml,
|
|
version,
|
|
autoLogAppEvents,
|
|
});
|
|
setIsLoaded(true);
|
|
|
|
// Check login status
|
|
window.FB.getLoginStatus((response: any) => {
|
|
if (response.status === 'connected') {
|
|
setIsLoggedIn(true);
|
|
getUserInfo(response.authResponse.accessToken);
|
|
}
|
|
});
|
|
};
|
|
|
|
document.head.appendChild(script);
|
|
} else {
|
|
setIsLoaded(true);
|
|
}
|
|
|
|
return () => {
|
|
// Cleanup if needed
|
|
};
|
|
}, [appId, cookie, xfbml, version, autoLogAppEvents]);
|
|
|
|
const getUserInfo = useCallback((accessToken: string) => {
|
|
window.FB.api('/me', { fields: 'name,email,picture' }, (response: FacebookUser) => {
|
|
if (response && !response.error) {
|
|
setUser(response);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
const login = useCallback((permissions: string[] = ['public_profile', 'email']) => {
|
|
return new Promise<FacebookLoginResponse>((resolve, reject) => {
|
|
if (!window.FB) {
|
|
reject(new Error('Facebook SDK not loaded'));
|
|
return;
|
|
}
|
|
|
|
window.FB.login((response: any) => {
|
|
if (response.status === 'connected') {
|
|
setIsLoggedIn(true);
|
|
getUserInfo(response.authResponse.accessToken);
|
|
resolve(response.authResponse);
|
|
} else if (response.status === 'not_authorized') {
|
|
reject({ error: 'not_authorized', errorDescription: 'User denied permissions' });
|
|
} else {
|
|
reject({ error: 'unknown', errorDescription: 'Login failed' });
|
|
}
|
|
}, { scope: permissions.join(',') });
|
|
});
|
|
}, [getUserInfo]);
|
|
|
|
const logout = useCallback(() => {
|
|
return new Promise<void>((resolve, reject) => {
|
|
if (!window.FB) {
|
|
reject(new Error('Facebook SDK not loaded'));
|
|
return;
|
|
}
|
|
|
|
window.FB.logout((response: any) => {
|
|
setIsLoggedIn(false);
|
|
setUser(null);
|
|
resolve();
|
|
});
|
|
});
|
|
}, []);
|
|
|
|
const getLoginStatus = useCallback(() => {
|
|
return new Promise<any>((resolve, reject) => {
|
|
if (!window.FB) {
|
|
reject(new Error('Facebook SDK not loaded'));
|
|
return;
|
|
}
|
|
|
|
window.FB.getLoginStatus((response: any) => {
|
|
resolve(response);
|
|
});
|
|
});
|
|
}, []);
|
|
|
|
return {
|
|
isLoaded,
|
|
isLoggedIn,
|
|
user,
|
|
login,
|
|
logout,
|
|
getLoginStatus,
|
|
};
|
|
};
|