parent
07b050b45c
commit
10881598de
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,79 @@ |
|||||||
|
import { |
||||||
|
useEffect, |
||||||
|
useRef, |
||||||
|
useState, |
||||||
|
useCallback, |
||||||
|
FormEvent, |
||||||
|
FocusEvent, |
||||||
|
ChangeEvent, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import { isValidEmail } from 'features/AuthServiceApp/helpers/isValidEmail' |
||||||
|
|
||||||
|
import { API_ROOT } from '../../config/routes' |
||||||
|
|
||||||
|
export const useOauth = () => { |
||||||
|
const [email, setEmail] = useState('') |
||||||
|
const [error, setError] = useState('') |
||||||
|
const [showEmailField, showShowEmailField] = useState(false) |
||||||
|
|
||||||
|
const formRef = useRef<HTMLFormElement>(null) |
||||||
|
|
||||||
|
const authorize = useCallback(async () => { |
||||||
|
if (!formRef.current) return |
||||||
|
|
||||||
|
const url = `${API_ROOT}/oauth` |
||||||
|
|
||||||
|
const res = await fetch(url, { |
||||||
|
body: new FormData(formRef.current), |
||||||
|
method: 'POST', |
||||||
|
}) |
||||||
|
|
||||||
|
if (res.ok && res.redirected) { |
||||||
|
formRef.current.submit() |
||||||
|
} else { |
||||||
|
const data = await res.json() |
||||||
|
|
||||||
|
if (data.error === 'Token missing email field') { |
||||||
|
showShowEmailField(true) |
||||||
|
} |
||||||
|
} |
||||||
|
}, []) |
||||||
|
|
||||||
|
const handleEmailChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) => { |
||||||
|
setEmail(value) |
||||||
|
} |
||||||
|
|
||||||
|
const handleEmailFocus = () => { |
||||||
|
setError('') |
||||||
|
} |
||||||
|
|
||||||
|
const handleEmailBlur = ({ target: { value } }: FocusEvent<HTMLInputElement>) => { |
||||||
|
if (!isValidEmail(value) && value) { |
||||||
|
setError('error_invalid_email_format') |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const handleSubmit = (e: FormEvent<HTMLFormElement>) => { |
||||||
|
e.preventDefault() |
||||||
|
|
||||||
|
if (error) return |
||||||
|
|
||||||
|
authorize() |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
authorize() |
||||||
|
}, [authorize]) |
||||||
|
|
||||||
|
return { |
||||||
|
email, |
||||||
|
error, |
||||||
|
formRef, |
||||||
|
handleEmailBlur, |
||||||
|
handleEmailChange, |
||||||
|
handleEmailFocus, |
||||||
|
handleSubmit, |
||||||
|
showEmailField, |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,137 @@ |
|||||||
|
import { Link } from 'react-router-dom' |
||||||
|
|
||||||
|
import styled, { css } from 'styled-components/macro' |
||||||
|
|
||||||
|
import { isMobileDevice } from 'config/userAgent' |
||||||
|
|
||||||
|
import { ButtonSolid } from 'features/Common' |
||||||
|
import { Error as ErrorBase } from 'features/AuthServiceApp/styled' |
||||||
|
import { HeaderLogo as HeaderLogoBase } from 'features/ProfileHeader/styled' |
||||||
|
|
||||||
|
import { Input as InputBase } from 'components/Input' |
||||||
|
|
||||||
|
export const Header = styled.div` |
||||||
|
position: absolute; |
||||||
|
padding: 30px 25px 0; |
||||||
|
` |
||||||
|
|
||||||
|
export const HeaderLogo = styled(HeaderLogoBase)` |
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
top: 20px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Content = styled.div` |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
height: 100vh; |
||||||
|
padding: 20px 25px; |
||||||
|
text-align: center; |
||||||
|
` |
||||||
|
|
||||||
|
export const DoneIcon = styled.div` |
||||||
|
width: 88px; |
||||||
|
height: 88px; |
||||||
|
margin-bottom: 20px; |
||||||
|
background-image: url(/images/done.svg); |
||||||
|
background-size: cover; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
width: 65px; |
||||||
|
height: 65px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Title = styled.div` |
||||||
|
margin-bottom: 40px; |
||||||
|
font-size: 24px; |
||||||
|
font-weight: bold; |
||||||
|
color: ${({ theme }) => theme.colors.white}; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
margin-bottom: 15px; |
||||||
|
line-height: 20px; |
||||||
|
font-size: 16px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Subtitle = styled.div` |
||||||
|
margin-bottom: 40px; |
||||||
|
font-size: 18px; |
||||||
|
line-height: 18px; |
||||||
|
color: ${({ theme }) => theme.colors.white}; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
margin-bottom: 15px; |
||||||
|
font-size: 12px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Form = styled.form` |
||||||
|
position: relative; |
||||||
|
display: flex; |
||||||
|
gap: 20px; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
gap: 10px; |
||||||
|
width: 100%; |
||||||
|
flex-direction: column; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Input = styled(InputBase)` |
||||||
|
width: 406px; |
||||||
|
height: 50px; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
width: 100%; |
||||||
|
height: 32px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const SubmitButton = styled(ButtonSolid)` |
||||||
|
width: 117.65px; |
||||||
|
height: 50px; |
||||||
|
font-size: 20px; |
||||||
|
font-weight: 600; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
width: 100%; |
||||||
|
height: 32px; |
||||||
|
font-size: 12px; |
||||||
|
` |
||||||
|
: ''}; |
||||||
|
` |
||||||
|
|
||||||
|
export const Text = styled.div` |
||||||
|
font-size: 12px; |
||||||
|
white-space: nowrap; |
||||||
|
color: rgba(255, 255, 255, 0.7); |
||||||
|
` |
||||||
|
|
||||||
|
export const StyledLink = styled(Link)` |
||||||
|
color: rgba(255, 255, 255, 0.7); |
||||||
|
text-decoration: underline; |
||||||
|
` |
||||||
|
|
||||||
|
export const Error = styled(ErrorBase)` |
||||||
|
position: absolute; |
||||||
|
left: 0; |
||||||
|
bottom: -25px; |
||||||
|
` |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
export const getRandomString = (length: number) => { |
||||||
|
let result = '' |
||||||
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' |
||||||
|
const charactersLength = characters.length |
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) { |
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength)) |
||||||
|
} |
||||||
|
|
||||||
|
return result |
||||||
|
} |
||||||
Loading…
Reference in new issue