2023-07-29 21:01:26 +02:00
|
|
|
// Hooks
|
|
|
|
import { useState, useContext } from 'react'
|
|
|
|
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|
|
|
import { useTranslation } from 'next-i18next'
|
|
|
|
// Context
|
|
|
|
import { ModalContext } from 'shared/context/modal-context.mjs'
|
|
|
|
// Dependencies
|
2023-08-28 08:40:39 +02:00
|
|
|
import { validateEmail, validateTld, horFlexClasses } from 'shared/utils.mjs'
|
2023-07-29 21:01:26 +02:00
|
|
|
// Components
|
|
|
|
import Link from 'next/link'
|
|
|
|
import { Robot } from 'shared/components/robot/index.mjs'
|
|
|
|
import { EmailValidButton } from 'shared/components/buttons/email-valid-button.mjs'
|
2023-08-28 08:40:39 +02:00
|
|
|
import { LeftIcon, HelpIcon, GoogleIcon, GitHubIcon } from 'shared/components/icons.mjs'
|
2023-07-29 21:01:26 +02:00
|
|
|
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
2023-08-25 11:33:56 +02:00
|
|
|
import { EmailInput } from 'shared/components/inputs.mjs'
|
2023-07-29 21:01:26 +02:00
|
|
|
|
|
|
|
// Translation namespaces used on this page
|
|
|
|
const namespaces = ['signup', 'errors']
|
|
|
|
|
|
|
|
const DarkLink = ({ href, txt }) => (
|
|
|
|
<Link className="decoration-1 underline text-medium font-medium hover:decoration-2" href={href}>
|
|
|
|
{txt}
|
|
|
|
</Link>
|
|
|
|
)
|
|
|
|
|
2023-08-28 08:40:39 +02:00
|
|
|
// FIXME: Hiding this now as it does nothing yet
|
|
|
|
const OAUTH = false
|
|
|
|
|
2023-07-29 21:01:26 +02:00
|
|
|
export const SignUp = () => {
|
|
|
|
// Context
|
|
|
|
const { setModal } = useContext(ModalContext)
|
|
|
|
|
|
|
|
const backend = useBackend()
|
|
|
|
const { t, i18n } = useTranslation(namespaces)
|
|
|
|
|
|
|
|
const [email, setEmail] = useState('')
|
|
|
|
const [emailValid, setEmailValid] = useState(false)
|
|
|
|
const [result, setResult] = useState(false)
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
|
2023-08-25 11:33:56 +02:00
|
|
|
const updateEmail = (value) => {
|
2023-07-29 21:01:26 +02:00
|
|
|
setEmail(value)
|
|
|
|
const valid = (validateEmail(value) && validateTld(value)) || false
|
|
|
|
setEmailValid(valid === true ? true : false)
|
|
|
|
}
|
|
|
|
|
|
|
|
const signupHandler = async (evt) => {
|
|
|
|
evt.preventDefault()
|
|
|
|
setLoading(true)
|
|
|
|
if (!emailValid) return
|
|
|
|
let res
|
|
|
|
try {
|
|
|
|
res = await backend.signUp({
|
|
|
|
email,
|
|
|
|
language: i18n.language,
|
|
|
|
setResult,
|
|
|
|
})
|
|
|
|
} catch (err) {
|
|
|
|
// Here to keep the stupid linter happy
|
|
|
|
console.log(err)
|
|
|
|
}
|
2023-08-13 18:00:43 +02:00
|
|
|
if (res.data.result === 'created') setResult('success')
|
2023-07-29 21:01:26 +02:00
|
|
|
else {
|
|
|
|
setModal(
|
|
|
|
<ModalWrapper bg="base-100 lg:bg-base-300">
|
|
|
|
<div className="bg-base-100 rounded-lg p-4 lg:px-8 max-w-xl lg:shadow-lg">
|
|
|
|
<h3>An error occured while trying to process your request</h3>
|
|
|
|
<Robot pose="ohno" className="m-auto w-56" embed />
|
|
|
|
<p className="text-lg">{t('err2')}</p>
|
|
|
|
<p className="text-lg">{t('err3')}</p>
|
|
|
|
<div className="flex flex-row gap-4 items-center justify-center p-8 flex-wrap">
|
|
|
|
<button className="btn btn-primary px-8" onClick={() => setResult(false)}>
|
|
|
|
<LeftIcon />
|
|
|
|
<span className="pl-2">{t('back')}</span>
|
|
|
|
</button>
|
|
|
|
<Link href="/support" className="btn btn-primary btn-outline px-8">
|
|
|
|
<HelpIcon />
|
|
|
|
<span className="pl-2">{t('contact')}</span>
|
|
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</ModalWrapper>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
setLoading(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
const loadingClasses = loading ? 'opacity-50' : ''
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<h2 className={`text-inherit ${loadingClasses}`}>
|
|
|
|
{result ? (
|
|
|
|
result === 'success' ? (
|
|
|
|
<span>{t('emailSent')}!</span>
|
|
|
|
) : (
|
|
|
|
<span>An error occured while trying to process your request</span>
|
|
|
|
)
|
|
|
|
) : (
|
|
|
|
<span>{t('signup:createAFreeSewingAccount')}</span>
|
|
|
|
)}
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
{result ? (
|
|
|
|
result === 'success' ? (
|
|
|
|
<>
|
|
|
|
<p className="text-inherit text-lg">
|
|
|
|
{t('checkYourInbox')} <b>FreeSewing.org</b>
|
|
|
|
</p>
|
|
|
|
<p className="text-inherit text-lg">{t('clickSignupLink')}</p>
|
|
|
|
<div className="flex flex-row gap-4 items-center justify-center p-8">
|
|
|
|
<button className="btn btn-ghost" onClick={() => setResult(false)}>
|
|
|
|
{t('back')}
|
|
|
|
</button>
|
|
|
|
<Link href="/support" className="btn btn-ghost">
|
|
|
|
{t('contact')}
|
|
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<Robot pose="ohno" className="m-auto w-56 text-inherit" embed />
|
|
|
|
<p className="text-inherit text-lg">{t('err2')}</p>
|
|
|
|
<p className="text-inherit text-lg">{t('err3')}</p>
|
|
|
|
<div className="flex flex-row gap-4 items-center justify-center p-8">
|
|
|
|
<button className="btn btn-ghost" onClick={() => setResult(false)}>
|
|
|
|
{t('back')}
|
|
|
|
</button>
|
|
|
|
<Link href="/support" className="btn btn-ghost">
|
|
|
|
{t('contact')}
|
|
|
|
</Link>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<p className={`text-inherit ${loadingClasses}`}>{t('toReceiveSignupLink')}:</p>
|
2023-08-28 08:40:39 +02:00
|
|
|
<form onSubmit={signupHandler}>
|
2023-08-25 11:33:56 +02:00
|
|
|
<EmailInput
|
2023-08-26 09:27:27 +02:00
|
|
|
id="signup-email"
|
2023-08-25 11:33:56 +02:00
|
|
|
label={t('emailAddress')}
|
2023-07-29 21:01:26 +02:00
|
|
|
placeholder={t('emailAddress')}
|
2023-08-25 11:33:56 +02:00
|
|
|
update={updateEmail}
|
2023-07-29 21:01:26 +02:00
|
|
|
/>
|
|
|
|
<EmailValidButton
|
|
|
|
email={email}
|
|
|
|
t={t}
|
|
|
|
validText={t('emailSignupLink')}
|
|
|
|
invalidText={t('pleaseProvideValidEmail')}
|
|
|
|
btnProps={{ type: 'submit' }}
|
|
|
|
/>
|
|
|
|
</form>
|
2023-08-28 08:40:39 +02:00
|
|
|
{OAUTH && (
|
|
|
|
<div className="grid grid-cols-2 gap-2 items-center mt-4">
|
|
|
|
{['Google', 'Github'].map((provider) => (
|
|
|
|
<button id={provider} className={`${horFlexClasses} btn btn-neutral btn-outline`}>
|
|
|
|
{provider === 'Google' ? <GoogleIcon stroke={0} /> : <GitHubIcon />}
|
|
|
|
<span>{t('signUpWithProvider', { provider })}</span>
|
|
|
|
</button>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
<p className={`text-inherit text-sm mt-0 opacity-80 text-center ${loadingClasses}`}>
|
2023-08-25 16:14:48 +02:00
|
|
|
<span className="block md:inline mb-2 md:mb-0">
|
|
|
|
{t('alreadyHaveAnAccount')} <DarkLink href="/signin" txt={t('signInHere')} />
|
|
|
|
</span>
|
|
|
|
<span className="hidden md:inline px-4">|</span>
|
|
|
|
<span className="block md:inline mb-2 md:mb-0">
|
|
|
|
{t('haveAV2Account')} <DarkLink href="/migrate" txt={t('migrateItHere')} />
|
|
|
|
</span>
|
2023-07-29 21:01:26 +02:00
|
|
|
</p>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|