127 lines
4.3 KiB
TypeScript
127 lines
4.3 KiB
TypeScript
import { useForm, SubmitHandler } from 'react-hook-form';
|
|
import icon from '../../assets/icon.png';
|
|
import { Link, useNavigate } from 'react-router-dom';
|
|
import { useContext, useState } from 'react';
|
|
import { AuthContext } from '../utils/AuthProvider.tsx';
|
|
import LoadingWheel from '../components/chat/LoadingWheel.tsx';
|
|
import { axiosClient } from '../App.tsx';
|
|
|
|
export type Inputs = {
|
|
username: string;
|
|
password: string;
|
|
};
|
|
|
|
export default function Login() {
|
|
const { setAuthorized } = useContext(AuthContext);
|
|
const [message, setMessage] = useState('');
|
|
const navigate = useNavigate();
|
|
const [IsLoading, setIsLoading] = useState<boolean>(false);
|
|
const { register, handleSubmit } = useForm<Inputs>({
|
|
mode: 'onChange',
|
|
});
|
|
|
|
const onSubmit: SubmitHandler<Inputs> = (data) => {
|
|
setIsLoading(true);
|
|
axiosClient
|
|
.post('/api/auth/login', data, {
|
|
withCredentials: true,
|
|
})
|
|
.then(() => {
|
|
setAuthorized(true);
|
|
setIsLoading(false);
|
|
console.log('redirecting');
|
|
navigate('/chat');
|
|
})
|
|
.catch((err) => {
|
|
if (err.response) {
|
|
setMessage('');
|
|
setTimeout(() => {
|
|
setMessage(err.response.data.message);
|
|
setIsLoading(false);
|
|
}, 100);
|
|
|
|
console.error(err);
|
|
}
|
|
});
|
|
};
|
|
return (
|
|
<>
|
|
<div className="bg-[#121212] flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8 h-screen">
|
|
<div className="sm:mx-auto sm:w-full sm:max-w-sm">
|
|
<img alt="chat" src={icon} className="mx-auto h-10 w-auto" />
|
|
<h2 className="text-white mt-10 text-center text-2xl font-bold leading-9 tracking-tight">
|
|
Log in to your account
|
|
</h2>
|
|
</div>
|
|
|
|
<div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
|
|
<div>
|
|
<label
|
|
htmlFor="username"
|
|
className="text-white block text-sm leading-6"
|
|
>
|
|
Username
|
|
</label>
|
|
<div>
|
|
<input
|
|
{...register('username')}
|
|
id="username"
|
|
name="username"
|
|
type="username"
|
|
required
|
|
autoFocus
|
|
autoComplete="username"
|
|
className="pl-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div className="flex items-center justify-between">
|
|
<label
|
|
htmlFor="password"
|
|
className="text-white block text-sm leading-6 "
|
|
>
|
|
Password
|
|
</label>
|
|
</div>
|
|
<div>
|
|
<input
|
|
{...register('password')}
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
required
|
|
autoComplete="current-password"
|
|
className="pl-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<button
|
|
disabled={IsLoading}
|
|
type="submit"
|
|
className="text-black bg-green-500 lex w-full justify-center rounded-md px-3 py-1.5 text-sm font-semibold leading-6 shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
|
>
|
|
{IsLoading ? <LoadingWheel /> : 'Log in'}
|
|
</button>
|
|
</div>
|
|
<div className="text-red-400 text-sm">{message}</div>
|
|
</form>
|
|
<p className="text-gray-300 mt-10 text-center text-sm">
|
|
Don't have account?{' '}
|
|
<Link
|
|
to="/signup"
|
|
className="text-green-400 leading-6 hover:text-green-600"
|
|
>
|
|
Sign up
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|