SignInWithGitHub.tsx58 lines · main
1import { Github } from 'lucide-react'
2import { useState } from 'react'
3import { toast } from 'sonner'
4import { Button } from 'ui'
5
6import { LastSignInWrapper } from './LastSignInWrapper'
7import { useLastSignIn } from '@/hooks/misc/useLastSignIn'
8import { BASE_PATH } from '@/lib/constants'
9import { captureCriticalError } from '@/lib/error-reporting'
10import { auth, buildPathWithParams } from '@/lib/gotrue'
11
12export const SignInWithGitHub = () => {
13 const [loading, setLoading] = useState(false)
14 const [_, setLastSignInUsed] = useLastSignIn()
15
16 async function handleGithubSignIn() {
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=github`
27 )
28
29 const { error } = await auth.signInWithOAuth({
30 provider: 'github',
31 options: { redirectTo },
32 })
33
34 if (error) throw error
35 else setLastSignInUsed('github')
36 } catch (error: any) {
37 toast.error(`Failed to sign in via GitHub: ${error.message}`)
38 captureCriticalError(error, 'sign in via GitHub')
39 setLoading(false)
40 }
41 }
42
43 return (
44 <LastSignInWrapper type="github">
45 <Button
46 block
47 onClick={handleGithubSignIn}
48 // set the width to 20 so that it matches the loading spinner and don't push the text when loading
49 icon={<Github width={20} height={18} />}
50 size="large"
51 type="default"
52 loading={loading}
53 >
54 Continue with GitHub
55 </Button>
56 </LastSignInWrapper>
57 )
58}