Skip to content

Instantly share code, notes, and snippets.

@dabit3
Last active January 17, 2021 02:39
Show Gist options
  • Select an option

  • Save dabit3/68b8a9f6a8e9de9bf01e54861a492e1a to your computer and use it in GitHub Desktop.

Select an option

Save dabit3/68b8a9f6a8e9de9bf01e54861a492e1a to your computer and use it in GitHub Desktop.
Next.js Authentication Component
import React, { useEffect, useState } from 'react';
import Auth from 'aws-amplify'
import { css } from 'emotion';
import { useRouter } from 'next/router'
const primaryColor = "rgba(0,118,255,0.9)"
const intitialFormState = {
username: '',
email: '',
password: '',
authCode: '',
formType: 'signUp'
}
export default function Profile() {
const [formState, setFormState] = useState(intitialFormState);
const [loading, setLoading] = useState(true);
const { username, email, password, authCode, formType } = formState;
const [user, setUser] = useState(null);
const router = useRouter()
const { signIn: setSignIn } = router.query
useEffect(() => {
checkUser();
if (setSignIn) {
setFormState(() => ({ ...formState, formType: 'signIn'}))
} else {
setFormState(intitialFormState)
}
}, [setSignIn]);
async function checkUser() {
try {
const userData = await Auth.currentAuthenticatedUser();
setUser(userData);
setFormState(() => ({ ...formState, formType: 'signedIn' }));
setLoading(false);
} catch (err) {
setUser(null);
setLoading(false);
}
}
function onChange(e) {
e.persist();
setFormState(() => ({ ...formState, [e.target.name]: e.target.value }));
}
function toggleFormType(formType) {
setFormState(state => ({ ...intitialFormState, formType }));
}
async function signUp() {
if (!username || !email || !password) return;
try {
await Auth.signUp({
username, password, attributes: { email }
});
setFormState(() => ({ ...formState, formType: 'confirmSignUp' }));
} catch (err) {
console.log('error signing up: ', err);
}
}
async function signIn() {
if (!password || !username) return;
try {
let user = await Auth.signIn(username, password);
console.log('Auth.signIn', user)
user = await Auth.currentAuthenticatedUser()
console.log('Auth.currentAuthenticatedUser', user)
const session = await new Promise((resolve, reject) => {
user.refreshSession(
user.signInUserSession.refreshToken,
(error, data) => {
if (error) {
reject(error)
}
resolve(data)
}
)
})
console.log('user.refreshSession', session)
setUser(user);
setFormState(() => ({ ...intitialFormState, formType: 'signedIn' }));
} catch (err) {
console.log('error signing in: ', err);
}
}
async function confirmSignUp() {
if (!authCode) return;
try {
await Auth.confirmSignUp(username, authCode);
await signIn();
} catch (err) {
console.log('error confirming signing up: ', err);
}
}
async function signOut() {
await Auth.signOut();
setFormState(() => ({ ...formState, formType: 'signUp' }));
setUser(null);
}
if (loading) return null
return (
<div>
<div className={containerStyle}>
{
formType === 'signUp' && (
<div className={formContainerStyle}>
<input
name="username"
value={username}
className={inputStyle}
placeholder="Username"
onChange={onChange}
/>
<input
name="email"
value={email}
className={inputStyle}
placeholder="Email"
onChange={onChange}
/>
<input
name="password"
value={password}
className={inputStyle}
type="password"
placeholder="Password"
onChange={onChange}
/>
<button onClick={signUp} className={buttonStyle}>
Sign Up
</button>
<p onClick={() => toggleFormType('signIn')} className={stateToggleStyle}>
Already signed up? Sign in.
</p>
</div>
)
}
{
formType === 'confirmSignUp' && (
<div className={formContainerStyle}>
<input
name="authCode"
value={authCode}
className={inputStyle}
placeholder="Authentication code"
onChange={onChange}
/>
<button onClick={confirmSignUp} className={buttonStyle}>
Confirm Sign Up
</button>
</div>
)
}
{
formType === 'signIn' && (
<div className={formContainerStyle}>
<input
name="username"
value={username}
className={inputStyle}
placeholder="Username"
onChange={onChange}
/>
<input
name="password"
value={password}
className={inputStyle}
type="password"
placeholder="Password"
onChange={onChange}
/>
<button onClick={signIn} className={buttonStyle}>
Sign In
</button>
<p onClick={() => toggleFormType('signUp')} className={stateToggleStyle}>
Need an account? Sign up.
</p>
</div>
)
}
</div>
{
formType === 'signedIn' && (
<div className={profileContainerStyle}>
<h1>Hello, {user.attributes.email}</h1>
<button onClick={signOut} className={buttonStyle}>
Sign Out
</button>
</div>
)
}
</div>
)
}
const containerStyle = css`
margin: 0 auto;
width: 960px;;
`
const profileContainerStyle = css`
display: flex;
flex-direction: column;
`
const stateToggleStyle = css`
color: ${primaryColor};
cursor: pointer;
text-align: center;
margin-top: 25px;
&:hover {
opacity: .8;
}
`
const formContainerStyle = css`
display: flex;
flex-direction: column;
width: 400px;
margin: 0 auto;
margin-top: 100px;
`
const inputStyle = css`
outline: none;
border: none;
border-bottom: 2px solid ${primaryColor};
margin: 4px 0px 0px;
height: 40px;
font-size: 20px;
`
const buttonStyle = css`
outline: none;
border: none;
cursor: pointer;
font-size: 18px;
min-width: 300px;
border-radius: 8px;
margin-top: 20px;
background-color: ${primaryColor};
color: white;
height: 50px;
text-shadow: 1px 1px 1px 1px rgba(0, 0, 0, .2);
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, .2);
&:hover {
opacity: .85;
}
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment