144 lines
3.6 KiB
TypeScript
144 lines
3.6 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,
|
|
};
|
|
};
|