2024-11-12 16:37:28 -06:00

96 lines
2.6 KiB
TypeScript

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';
import Navbar from './Navbar';
function Login() {
document.title = 'LinkLogger | Login';
const [username, setUsername] = useState('');
const [password, setPassword] = 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);
try {
const res = await axios.post(
'/api/auth/token',
new URLSearchParams({
username: username,
password: password,
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
}
);
if (res.status === 200) {
navigate('/dashboard');
}
} catch (error: unknown) {
if (axios.isAxiosError(error)) {
const customErrorMessage = error.response?.data?.detail || null;
setPassword('');
setError(customErrorMessage || 'An error occurred. Please try again.');
} else {
setPassword('');
setError('Unknown error. Please try again.');
}
} finally {
setIsSubmitting(false);
}
};
return (
<>
<Navbar />
<div id={styles.container}>
<p id={styles.loginText}>Log In</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}
onChange={(e) => setPassword(e.target.value)}
required
/>
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit'}
</button>
</form>
<hr></hr>
<p id={styles.bottomText}>
Don't have an account?{' '}
<Link to="/signup" className={styles.link}>
Create one now
</Link>
</p>
</header>
</div>
</div>
</>
);
}
export default Login;