aboutsummaryrefslogtreecommitdiff
path: root/app/src/components/Signup.tsx
blob: 293b51ab26db1913d76e66fac465ac52946425a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { useState, FormEvent } from 'react';
import styles from '../styles/Login.module.css';
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

function Signup() {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [passwordConfirm, setPasswordConfirm] = useState('');
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const navigate = useNavigate();

    const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setIsSubmitting(true);

        if (password !== passwordConfirm) {
            setPassword('');
            setPasswordConfirm('');
            return setError('Passwords do not match.');
        }

        try {
            const res = await axios.post(
                '/api/users/register',
                new URLSearchParams({
                    username: username,
                    password: password,
                }),
                {
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                }
            );

            if (res.status === 200) {
                navigate('/login');
            }
        } catch (error: unknown) {
            if (axios.isAxiosError(error)) {
                const customErrorMessage = error.response?.data?.detail || null;
                setUsername('');
                setPassword('');
                setPasswordConfirm('');
                setError(customErrorMessage || 'An error occurred. Please try again.');
            } else {
                setUsername('');
                setPassword('');
                setPasswordConfirm('');
                setError('Unknown error. Please try again.');
            }
        } finally {
            setIsSubmitting(false);
        }
    };

    return (
        <div id={styles.container}>
            <p id={styles.signupText}>Sign up</p>
            <p id={styles.error} className={error ? 'visible' : 'hidden'}>
                {error}
            </p>
            <div>
                <header>
                    <hr></hr>
                    <form onSubmit={handleSubmit}>
                        <input
                            type="text"
                            placeholder="username"
                            value={username}
                            onChange={(e) => setUsername(e.target.value)}
                            required
                        />
                        <input
                            type="password"
                            placeholder="password"
                            value={password}
                            minLength={8}
                            onChange={(e) => setPassword(e.target.value)}
                            required
                        />
                        <input
                            type="password"
                            placeholder="confirm password"
                            value={passwordConfirm}
                            minLength={8}
                            onChange={(e) => setPasswordConfirm(e.target.value)}
                            required
                        />
                        <button type="submit" disabled={isSubmitting}>
                            {isSubmitting ? 'Submitting...' : 'Submit'}
                        </button>
                    </form>
                    <hr></hr>
                    <p id={styles.bottomText}>Already have an account? <Link to="/login" className={styles.link}>Log in here.</Link></p>
                </header>
            </div>
        </div>
    );
}

export default Signup;