'use client' import { useState } from 'react' import { useLocale, useTranslations } from 'next-intl' import { createClient } from '@/lib/supabase/client' import { Button } from '@/components/ui/button' import { Loader2, KeyRound } from 'lucide-react' import { getErrorMessage, type ErrorLocale } from '@/lib/errors/get-error-message' import { GitHubMark, GoogleMark, MicrosoftMark } from '@/components/ui/provider-marks' import type { ResolvedProvider } from '@/lib/auth/gotrue-providers' /** * Render the brand mark for a known provider, or a generic key icon for * custom OIDC providers. */ function ProviderMark({ provider }: { provider: ResolvedProvider }) { if (provider.id === 'google') return else if (provider.id === 'azure') return else if (provider.id === 'github') return else return } /** * Generic OAuth login button. Works with any Supabase GoTrue provider. * * For known providers (Google, GitHub, etc.) the button shows the brand * name; for custom OIDC providers it shows "Sign in with SSO" style text. * * Kicks off the Supabase OAuth redirect, with flow=oauth so * /auth/callback can tag failures. */ export function OAuthButton({ provider, onError, compact = false, next, }: { provider: ResolvedProvider onError: (message: string) => void compact?: boolean /** * Post-auth destination, already passed through safeReturnTo by the caller. * Forwarded to /auth/callback as `next` so an OAuth sign-in or sign-up that * started from the MCP consent page (/login?next=/api/mcp-oauth/authorize…) * resumes the consent flow instead of landing on the dashboard. '/' (the * safeReturnTo fallback) means no destination and is not forwarded. */ next?: string }) { const [isRedirecting, setIsRedirecting] = useState(false) const supabase = createClient() const tAuth = useTranslations('auth') const errorLocale = useLocale() as ErrorLocale const handleClick = async () => { setIsRedirecting(true) try { const callback = new URL('/auth/callback', window.location.origin) callback.searchParams.set('flow', 'oauth') if (next && next !== '/') callback.searchParams.set('next', next) const { error } = await supabase.auth.signInWithOAuth({ provider: provider.id as Parameters[0]['provider'], options: { redirectTo: callback.toString(), }, }) if (error) { onError(getErrorMessage(error, { context: 'auth', locale: errorLocale })) setIsRedirecting(false) } } catch (error) { onError(getErrorMessage(error, { context: 'auth', locale: errorLocale })) setIsRedirecting(false) } } const label = tAuth('continue_with_provider', { provider: provider.label }) return ( ) }