// Hooks
import { useState, useEffect, useContext } from 'react'
import { useAccount } from 'shared/hooks/use-account.mjs'
import { useTranslation } from 'next-i18next'
import { useBackend } from 'shared/hooks/use-backend.mjs'
import { useRouter } from 'next/router'
import { useLoadingStatus } from 'shared/hooks/use-loading-status.mjs'
// Components
import Link from 'next/link'
import { EmailIcon, KeyIcon, RightIcon, WarningIcon } from 'shared/components/icons.mjs'
const darkLinkClasses = 'decoration-1 underline text-medium font-medium hover:decoration-2'
const UsernameField = ({ username, setUsername, t }) => (
setUsername(evt.target.value)}
placeholder={t('signin:emailUsernameId')}
className="input input-bordered w-full text-base-content"
autoFocus={true}
value={username}
/>
)
const PasswordField = ({ password, setPassword, revealPassword, setRevealPassword, t }) => (
setPassword(evt.target.value)}
placeholder={t('signin:password')}
className="input input-bordered w-full text-base-content"
autoFocus={true}
value={password}
/>
)
export const ButtonText = ({ children }) => (
{children}
)
export const SignIn = () => {
const { setAccount, setToken, seenUser, setSeenUser } = useAccount()
const { t } = useTranslation(['signin', 'signup', 'toast'])
const backend = useBackend()
const router = useRouter()
const { setLoadingStatus, LoadingStatus } = useLoadingStatus()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [revealPassword, setRevealPassword] = useState(false)
const [magicLink, setMagicLink] = useState(true)
const [signInFailed, setSignInFailed] = useState(false)
const [magicLinkSent, setMagicLinkSent] = useState(false)
const [seenBefore, setSeenBefore] = useState(false)
useEffect(() => {
if (typeof window !== 'undefined' && signInFailed) {
window.setTimeout(() => setSignInFailed(false), 1750)
}
}, [signInFailed])
// Avoid SSR rendering mismatch by setting this in effect
useEffect(() => {
if (seenUser) {
setSeenBefore(seenUser)
setUsername(seenUser)
} else {
setSeenBefore(false)
setUsername('')
}
}, [seenUser])
const signinHandler = async (evt) => {
evt.preventDefault()
setLoadingStatus([true, 'processingUpdate'])
const result = magicLink
? await backend.signIn({ username, password: false })
: await backend.signIn({ username, password })
// Sign-in succeeded
console.log(result.response.response)
if (result.success) {
let msg
if (magicLink) {
setLoadingStatus([true, t('singup:emailSent'), true, true])
setMagicLinkSent(true)
msg = t('signup:emailSent')
} else {
setAccount(result.data.account)
setToken(result.data.token)
setSeenUser(result.data.account.username)
msg = t('signin:welcomeBackName', { name: result.data.account.username })
setLoadingStatus([true, msg, true, true])
router.push('/account')
}
return toast.success({msg})
}
// Sign-in failed
if (result.response?.response?.status === 401) {
const msg = magicLink ? t('notFound') : t('signInFailed')
setSignInFailed(msg)
setLoadingStatus([true, msg, true, false])
}
// Bad request
if (result.status === 400) {
let msg
if (result.data.error === 'usernameMissing') msg = t('usernameMissing')
else if (result.data.error === 'passwordMissing') msg = t('passwordMissing')
setSignInFailed(msg)
setLoadingStatus([true, msg, true, false])
}
}
const btnClasses = `btn capitalize w-full mt-4 ${
signInFailed ? 'btn-warning' : 'btn-primary'
} transition-colors ease-in-out duration-300`
const noBueno = (
{signInFailed}
)
if (magicLinkSent)
return (
<>
{t('signup:emailSent')}
{t('signup:checkYourInbox')} FreeSewing.org
{t('clickSigninLink')}
{t('signup:contact')}
>
)
return (
<>
{seenBefore ? t('signin:welcomeBackName', { name: seenUser }) : t('signin:welcome')}
{t('signin:signInToThing', { thing: 'FreeSewing' })}
{!seenBefore && }
{magicLink ? (
) : (
<>
>
)}
-
{seenBefore ? (
<>
- |
-
>
) : null}
{!seenBefore ? (
{t('signin:dontHaveAnAccount')}{' '}
{t('signin:signUpHere')}
) : null}
>
)
}