"use client" import type { Account } from "better-auth" import type { SocialProvider } from "better-auth/social-providers" import { Loader2 } from "lucide-react" import { useContext, useState } from "react" import { useIsOverflow } from "../../../hooks/use-is-overflow" import { AuthUIContext } from "../../../lib/auth-ui-provider" import type { Provider } from "../../../lib/social-providers" import { cn, getLocalizedError } from "../../../lib/utils" import type { AuthLocalization } from "../../../localization/auth-localization" import type { Refetch } from "../../../types/refetch" import { Button } from "../../ui/button" import { Card } from "../../ui/card" import { Skeleton } from "../../ui/skeleton" import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip" import type { SettingsCardClassNames } from "../shared/settings-card" export interface ProviderCellProps { className?: string classNames?: SettingsCardClassNames account?: Account | null isPending?: boolean localization?: Partial other?: boolean provider: Provider refetch?: Refetch } export function ProviderCell({ className, classNames, account, localization, other, provider, refetch }: ProviderCellProps) { const { authClient, basePath, baseURL, localization: contextLocalization, mutators: { unlinkAccount }, viewPaths, toast, localizeErrors } = useContext(AuthUIContext) localization = { ...contextLocalization, ...localization } const [isLoading, setIsLoading] = useState(false) const handleLink = async () => { setIsLoading(true) const callbackURL = `${baseURL}${basePath}/${viewPaths.CALLBACK}?redirectTo=${encodeURIComponent(window.location.pathname)}` try { if (other) { await authClient.oauth2.link({ providerId: provider.provider as SocialProvider, callbackURL, fetchOptions: { throw: true } }) } else { await authClient.linkSocial({ provider: provider.provider as SocialProvider, callbackURL, fetchOptions: { throw: true } }) } } catch (error) { toast({ variant: "error", message: getLocalizedError({ error, localization, localizeErrors }) }) setIsLoading(false) } } const handleUnlink = async () => { setIsLoading(true) try { await unlinkAccount({ accountId: account?.accountId, providerId: provider.provider }) await refetch?.() } catch (error) { toast({ variant: "error", message: getLocalizedError({ error, localization, localizeErrors }) }) } setIsLoading(false) } return ( ) } function ProviderCellContent({ account, classNames, provider }: { account?: Account | null classNames?: SettingsCardClassNames provider: Provider }) { if (account) { return ( ) } return (
) } function ConnectedProviderContent({ account, classNames, provider }: { account: Account classNames?: SettingsCardClassNames provider: Provider }) { const { hooks: { useAccountInfo } } = useContext(AuthUIContext) const { data: accountInfo, isPending } = useAccountInfo({ query: { accountId: account.accountId } }) const email = accountInfo?.user.email const { ref: emailRef, isOverflow } = useIsOverflow() const emailElement = isPending ? ( ) : email ? ( {email} ) : null const content = ( ) const wrapperClassName = "flex min-w-0 flex-1 items-center gap-3" if (email && isOverflow) { return (
{content}

{email}

) } return (
{content}
) } function ProviderContent({ accountInfo, classNames, provider }: { accountInfo?: React.ReactNode classNames?: SettingsCardClassNames provider: Provider }) { return ( <> {provider.icon && ( )}
{provider.name}
{accountInfo}
) }