import { Box, Link, Typography } from '@mui/joy'
import { useQueryClient } from '@tanstack/react-query'
import React from 'react'
import { useNavigate } from 'react-router-dom'
import { useNotification } from '../../service/NotificationProvider'
import { login, signUp } from '../../utils/Fetcher'
import {
AuthPasswordField,
AuthSubmitButton,
AuthTextField,
LegalLinks,
} from './AuthFields'
import AuthShell from './AuthShell'
const SignupView = () => {
const [username, setUsername] = React.useState('')
const [password, setPassword] = React.useState('')
const Navigate = useNavigate()
const queryClient = useQueryClient()
const [displayName, setDisplayName] = React.useState('')
const [email, setEmail] = React.useState('')
const [usernameError, setUsernameError] = React.useState('')
const [passwordError, setPasswordError] = React.useState('')
const [emailError, setEmailError] = React.useState('')
const [displayNameError, setDisplayNameError] = React.useState('')
const [isSubmitting, setIsSubmitting] = React.useState(false)
const { showError } = useNotification()
const handleLogin = (username, password) => {
login(username, password).then(response => {
if (response.status === 200) {
response.json().then(res => {
localStorage.setItem('token', res.token)
localStorage.setItem('token_expiry', res.expire)
// Invalidate user profile queries to ensure fresh data
queryClient.invalidateQueries(['userProfile'])
// The "how did you hear about us" step (/heard-about) is
// temporarily skipped; new accounts go straight to circle setup.
// Re-enable by navigating to '/heard-about' again — that view
// already forwards to '/circle-setup' when done.
Navigate('/circle-setup', { replace: true })
})
} else {
console.log('Login failed', response)
// Navigate('/login')
}
})
}
const handleSignUpValidation = () => {
// Reset errors before validation
setUsernameError(null)
setPasswordError(null)
setDisplayNameError(null)
setEmailError(null)
let isValid = true
if (!username.trim()) {
setUsernameError('Username is required')
isValid = false
}
if (username.length < 4) {
setUsernameError('Username must be at least 4 characters')
isValid = false
}
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
setEmailError('Invalid email address')
isValid = false
}
if (password.length < 8) {
setPasswordError('Password must be between 8 and 64 characters')
isValid = false
}
if (password.length > 64) {
setPasswordError('Password must be between 8 and 64 characters')
isValid = false
}
if (!displayName.trim()) {
setDisplayNameError('Display name is required')
isValid = false
}
// display name should only contain letters and spaces and numbers:
if (!/^[a-zA-Z0-9 ]+$/.test(displayName)) {
setDisplayNameError('Display name can only contain letters and numbers')
isValid = false
}
// username should only contain lowercase letters, numbers, dot and dash:
if (!/^[a-z0-9.-]+$/.test(username)) {
setUsernameError(
'Username can only contain lowercase letters, numbers, dot and dash',
)
isValid = false
}
return isValid
}
const handleSubmit = async e => {
e.preventDefault()
if (!handleSignUpValidation()) {
return
}
setIsSubmitting(true)
signUp(username, password, displayName, email)
.then(response => {
if (response.status === 201) {
handleLogin(username, password)
} else if (response.status === 403) {
showError({
title: 'Signup Failed',
message: 'Signup disabled, please contact admin',
})
} else {
console.log('Signup failed')
response.json().then(res => {
showError({
title: 'Signup Failed',
message: res.error || 'An error occurred during signup',
})
})
}
})
.finally(() => setIsSubmitting(false))
}
return (
}
logoSize={0}
>
{
setDisplayNameError(null)
setDisplayName(e.target.value)
}}
/>
{
setUsernameError(null)
setUsername(e.target.value.trim())
}}
/>
{
setEmailError(null)
setEmail(e.target.value.trim())
}}
/>
{
setPasswordError(null)
setPassword(e.target.value)
}}
/>
Create account
By creating an account you agree to our Terms of Service and Privacy
Policy.
Already have an account?{' '}
Navigate('/login')}
>
Sign in
)
}
export default SignupView