SignInWithGitHub.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { Github } from 'lucide-react'
  2. import { useState } from 'react'
  3. import { toast } from 'sonner'
  4. import { Button } from 'ui'
  5. import { LastSignInWrapper } from './LastSignInWrapper'
  6. import { useLastSignIn } from '@/hooks/misc/useLastSignIn'
  7. import { BASE_PATH } from '@/lib/constants'
  8. import { captureCriticalError } from '@/lib/error-reporting'
  9. import { auth, buildPathWithParams } from '@/lib/gotrue'
  10. export const SignInWithGitHub = () => {
  11. const [loading, setLoading] = useState(false)
  12. const [_, setLastSignInUsed] = useLastSignIn()
  13. async function handleGithubSignIn() {
  14. setLoading(true)
  15. try {
  16. // redirects to /sign-in to check if the user has MFA setup (handled in SignInLayout.tsx)
  17. const redirectTo = buildPathWithParams(
  18. `${
  19. process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview'
  20. ? location.origin
  21. : process.env.NEXT_PUBLIC_SITE_URL
  22. }${BASE_PATH}/sign-in-mfa?method=github`
  23. )
  24. const { error } = await auth.signInWithOAuth({
  25. provider: 'github',
  26. options: { redirectTo },
  27. })
  28. if (error) throw error
  29. else setLastSignInUsed('github')
  30. } catch (error: any) {
  31. toast.error(`Failed to sign in via GitHub: ${error.message}`)
  32. captureCriticalError(error, 'sign in via GitHub')
  33. setLoading(false)
  34. }
  35. }
  36. return (
  37. <LastSignInWrapper type="github">
  38. <Button
  39. block
  40. onClick={handleGithubSignIn}
  41. // set the width to 20 so that it matches the loading spinner and don't push the text when loading
  42. icon={<Github width={20} height={18} />}
  43. size="large"
  44. type="default"
  45. loading={loading}
  46. >
  47. Continue with GitHub
  48. </Button>
  49. </LastSignInWrapper>
  50. )
  51. }