2
0

Add authentication

This commit is contained in:
Baptiste Arnaud
2021-11-29 15:19:07 +01:00
parent 68dd491eca
commit 5e14a94dea
51 changed files with 5036 additions and 90 deletions

View File

@ -0,0 +1,26 @@
import React from 'react'
import { NextChakraLink } from '../nextChakra/NextChakraLink'
import { Text } from '@chakra-ui/react'
type Props = {
type: 'register' | 'signin'
}
export const AuthSwitcher = ({ type }: Props) => (
<>
{type === 'signin' ? (
<Text>
Don't have an account?{' '}
<NextChakraLink href="/register" color="blue.500" textDecor="underline">
Sign up for free
</NextChakraLink>
</Text>
) : (
<Text>
Already have an account?{' '}
<NextChakraLink href="/signin" color="blue.500" textDecor="underline">
Sign in
</NextChakraLink>
</Text>
)}
</>
)

View File

@ -0,0 +1,25 @@
import { FlexProps, Flex, Box, Divider, Text } from '@chakra-ui/react'
import { useColorModeValue } from '@chakra-ui/system'
import React from 'react'
export const DividerWithText = (props: FlexProps) => {
const { children, ...flexProps } = props
return (
<Flex align="center" color="gray.300" {...flexProps}>
<Box flex="1">
<Divider borderColor="currentcolor" />
</Box>
<Text
as="span"
px="3"
color={useColorModeValue('gray.600', 'gray.400')}
fontWeight="medium"
>
{children}
</Text>
<Box flex="1">
<Divider borderColor="currentcolor" />
</Box>
</Flex>
)
}

View File

@ -0,0 +1,76 @@
import {
Button,
HTMLChakraProps,
Input,
Stack,
HStack,
useToast,
} from '@chakra-ui/react'
import React, { ChangeEvent, FormEvent, useEffect } from 'react'
import { useState } from 'react'
import { signIn, useSession } from 'next-auth/react'
import { DividerWithText } from './DividerWithText'
import { SocialLoginButtons } from './SocialLoginButtons'
import { useRouter } from 'next/router'
type Props = {
defaultEmail?: string
}
export const SignInForm = ({
defaultEmail,
}: Props & HTMLChakraProps<'form'>) => {
const router = useRouter()
const { status } = useSession()
const [authLoading, setAuthLoading] = useState(false)
const [emailValue, setEmailValue] = useState(defaultEmail ?? '')
const toast = useToast({
position: 'top-right',
})
useEffect(() => {
if (status === 'authenticated') router.replace('/typebots')
}, [status, router])
const handleEmailChange = (e: ChangeEvent<HTMLInputElement>) =>
setEmailValue(e.target.value)
const handleEmailSubmit = async (e: FormEvent) => {
e.preventDefault()
setAuthLoading(true)
await signIn('email', {
email: emailValue,
redirect: false,
})
toast({
status: 'success',
title: 'Success!',
description: 'Check your inbox to sign in',
})
setAuthLoading(false)
}
return (
<Stack spacing="4">
<SocialLoginButtons />
<DividerWithText mt="6">Or with your email</DividerWithText>
<HStack as="form" onSubmit={handleEmailSubmit}>
<Input
name="email"
type="email"
autoComplete="email"
placeholder="email@company.com"
required
value={emailValue}
onChange={handleEmailChange}
/>
<Button
type="submit"
isLoading={
['loading', 'authenticated'].includes(status) || authLoading
}
>
Submit
</Button>
</HStack>
</Stack>
)
}

View File

@ -0,0 +1,46 @@
import { FacebookLogo, GithubLogo, GoogleLogo } from 'assets/logos'
import { Stack, Button } from '@chakra-ui/react'
import { signIn, useSession } from 'next-auth/react'
import React from 'react'
export const SocialLoginButtons = () => {
const { status } = useSession()
const handleGitHubClick = async () => signIn('github')
const handleGoogleClick = async () => signIn('google')
const handleFacebookClick = async () => signIn('facebook')
return (
<Stack>
<Button
leftIcon={<GithubLogo />}
colorScheme="gray"
onClick={handleGitHubClick}
data-testid="github"
isLoading={['loading', 'authenticated'].includes(status)}
>
Continue with GitHub
</Button>
<Button
leftIcon={<GoogleLogo />}
colorScheme="gray"
onClick={handleGoogleClick}
data-testid="google"
isLoading={['loading', 'authenticated'].includes(status)}
>
Continue with Google
</Button>
<Button
leftIcon={<FacebookLogo />}
colorScheme="gray"
onClick={handleFacebookClick}
data-testid="facebook"
isLoading={['loading', 'authenticated'].includes(status)}
>
Continue with Facebook
</Button>
</Stack>
)
}