import { IconDiscord, IconGithub, IconGoogle, IconTwitter, } from "@/assets/icons"; import { useOAuth2 } from "@/hooks"; import type { SocialOptionArray as SocialLoginsType, SocialOption, } from "@/types"; import type React from "react"; import { useEffect } from "react"; /** * Props for the SocialLogins component. * * @interface SocialLoginsProps * @property {SocialLoginsType} socialLogins - An object containing the social login options. */ export interface SocialLoginsProps { socialLogins: SocialLoginsType; } /** * SocialLogins component renders social login buttons and handles OAuth2 authentication flow. * * @param {SocialLoginsProps} props - The properties for the SocialLogins component. * @param {SocialOption[]} props.socialLogins - An array of social login providers to display. * * @returns {JSX.Element} The rendered social login buttons. * * @example * * * @remarks * This component uses the `useOAuth2` hook to initiate and handle OAuth2 authentication. * It stores the selected provider in localStorage and processes the OAuth callback. * * @component */ export function SocialLogins({ socialLogins }: SocialLoginsProps) { const { initiateOAuth, handleOAuthCallback } = useOAuth2(); useEffect(() => { const url = new URL(window.location.href); const code = url.searchParams.get("code"); const provider = localStorage.getItem("moon_auth_provider") as SocialOption; if (code && provider) { handleOAuthCallback(provider, code) .then(() => { // Clear the code from the URL url.searchParams.delete("code"); window.history.replaceState({}, "", url.toString()); }) .catch((error) => console.error("OAuth callback error:", error)) .finally(() => { localStorage.removeItem("moon_auth_provider"); }); } }, [handleOAuthCallback]); const handleSignIn = (provider: SocialOption) => { localStorage.setItem("moon_auth_provider", provider); initiateOAuth(provider); }; const socialButtons: { provider: SocialOption; Icon: React.ComponentType<{ className?: string }>; bgColor: string; }[] = [ { provider: "discord", Icon: IconDiscord, bgColor: "bg-accent-color" }, { provider: "github", Icon: IconGithub, bgColor: "bg-gray-900" }, { provider: "twitter", Icon: IconTwitter, bgColor: "bg-sky-500" }, { provider: "google", Icon: IconGoogle, bgColor: "bg-zinc-50" }, ]; return ( <> {socialButtons .filter(({ provider }) => socialLogins.includes(provider)) .map(({ provider, Icon, bgColor }) => (
handleSignIn(provider)} >
))} ); }