153 lines
No EOL
4.6 KiB
TypeScript
153 lines
No EOL
4.6 KiB
TypeScript
import React, { useState } from 'react'
|
|
import { withCookies, Cookies } from 'react-cookie'
|
|
import { createPortal } from 'react-dom'
|
|
|
|
import api from '~utils/api'
|
|
import { accountState } from '~utils/accountState'
|
|
|
|
import Button from '~components/Button'
|
|
import Fieldset from '~components/Fieldset'
|
|
import Modal from '~components/Modal'
|
|
import Overlay from '~components/Overlay'
|
|
|
|
import './index.scss'
|
|
|
|
interface Props {
|
|
cookies: Cookies
|
|
close: () => void
|
|
}
|
|
|
|
interface ErrorMap {
|
|
[index: string]: string
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
|
|
const LoginModal = (props: Props) => {
|
|
const emailInput: React.RefObject<HTMLInputElement> = React.createRef()
|
|
const passwordInput: React.RefObject<HTMLInputElement> = React.createRef()
|
|
const form: React.RefObject<HTMLInputElement>[] = [emailInput, passwordInput]
|
|
|
|
const [formValid, setFormValid] = useState(false)
|
|
const [errors, setErrors] = useState<ErrorMap>({
|
|
email: '',
|
|
password: ''
|
|
})
|
|
|
|
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
event.preventDefault()
|
|
|
|
const { name, value } = event.target
|
|
let newErrors = errors
|
|
|
|
switch(name) {
|
|
case 'email':
|
|
errors.email = emailRegex.test(value)
|
|
? ''
|
|
: 'That email address is not valid'
|
|
break
|
|
|
|
case 'password':
|
|
errors.password = value.length == 0
|
|
? 'Please enter your password'
|
|
: ''
|
|
break
|
|
|
|
default:
|
|
break
|
|
}
|
|
|
|
setErrors(newErrors)
|
|
setFormValid(validateForm())
|
|
}
|
|
|
|
function validateForm() {
|
|
let valid = true
|
|
|
|
Object.values(form).forEach(
|
|
(input) => input.current?.value.length == 0 && (valid = false)
|
|
)
|
|
|
|
Object.values(errors).forEach(
|
|
(error) => error.length > 0 && (valid = false)
|
|
)
|
|
|
|
return valid
|
|
}
|
|
|
|
function submit(event: React.FormEvent) {
|
|
event.preventDefault()
|
|
|
|
const body = {
|
|
email: emailInput.current?.value,
|
|
password: passwordInput.current?.value,
|
|
grant_type: 'password'
|
|
}
|
|
|
|
if (formValid) {
|
|
api.login(body)
|
|
.then((response) => {
|
|
const cookies = props.cookies
|
|
|
|
const cookieObj = {
|
|
user_id: response.data.user.id,
|
|
username: response.data.user.username,
|
|
access_token: response.data.access_token
|
|
}
|
|
|
|
cookies.set('user', cookieObj, { path: '/'})
|
|
accountState.account.authorized = true
|
|
accountState.account.user = {
|
|
id: cookieObj.user_id,
|
|
username: cookieObj.username
|
|
}
|
|
|
|
props.close()
|
|
}, (error) => {
|
|
console.error(error)
|
|
})
|
|
}
|
|
}
|
|
|
|
return (
|
|
createPortal(
|
|
<div>
|
|
<Modal
|
|
title="Log in"
|
|
styleName="LoginForm"
|
|
close={ () => {} }
|
|
>
|
|
<form className="form" onSubmit={submit}>
|
|
<div id="fields">
|
|
<Fieldset
|
|
fieldName="email"
|
|
placeholder="Email address"
|
|
onChange={handleChange}
|
|
error={errors.email}
|
|
ref={emailInput}
|
|
/>
|
|
|
|
<Fieldset
|
|
fieldName="password"
|
|
placeholder="Password"
|
|
onChange={handleChange}
|
|
error={errors.password}
|
|
ref={passwordInput}
|
|
/>
|
|
</div>
|
|
<div id="ModalBottom">
|
|
<a>Forgot your password?</a>
|
|
<Button disabled={!formValid}>Log in</Button>
|
|
</div>
|
|
</form>
|
|
</Modal>
|
|
<Overlay onClick={props.close} />
|
|
</div>,
|
|
document.body
|
|
)
|
|
)
|
|
}
|
|
|
|
export default withCookies(LoginModal) |