SignInWithCustom.tsx48 lines · main
1import { useState } from 'react'
2import { toast } from 'sonner'
3import { Button } from 'ui'
4
5import { BASE_PATH } from '@/lib/constants'
6import { captureCriticalError } from '@/lib/error-reporting'
7import { auth, buildPathWithParams } from '@/lib/gotrue'
8
9interface SignInWithCustomProps {
10 providerName: string
11}
12
13export const SignInWithCustom = ({ providerName }: SignInWithCustomProps) => {
14 const [loading, setLoading] = useState(false)
15
16 async function handleCustomSignIn() {
17 setLoading(true)
18
19 try {
20 // redirects to /sign-in to check if the user has MFA setup (handled in SignInLayout.tsx)
21 const redirectTo = buildPathWithParams(
22 `${
23 process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview'
24 ? location.origin
25 : process.env.NEXT_PUBLIC_SITE_URL
26 }${BASE_PATH}/sign-in-mfa?method=${providerName.toLowerCase()}`
27 )
28
29 const { error } = await auth.signInWithOAuth({
30 // @ts-expect-error - providerName is a string
31 provider: providerName.toLowerCase(),
32 options: { redirectTo, scopes: 'email' },
33 })
34
35 if (error) throw error
36 } catch (error: any) {
37 toast.error(`Failed to sign in via ${providerName}: ${error.message}`)
38 captureCriticalError(error, `sign in via ${providerName}`)
39 setLoading(false)
40 }
41 }
42
43 return (
44 <Button block onClick={handleCustomSignIn} size="large" type="default" loading={loading}>
45 Continue with {providerName}
46 </Button>
47 )
48}