84 lines
2.9 KiB
JavaScript
84 lines
2.9 KiB
JavaScript
import React, {useContext, useEffect, useState} from 'react';
|
|
import Navbar from "./Navbar";
|
|
import {Link} from "react-router-dom";
|
|
import {Input} from "../custom";
|
|
import {AuthContext} from "../App";
|
|
import {login} from "../auth";
|
|
import {toast} from "react-toastify";
|
|
import {useForm} from "react-hook-form";
|
|
|
|
const background = require('../assets/background.png')
|
|
|
|
function Login(props) {
|
|
const {register, handleSubmit, errors} = useForm();
|
|
const [error, setError] = useState("")
|
|
const [status, setStatus] = useState("Sign In")
|
|
const {authState, authDispatch} = useContext(AuthContext)
|
|
const [canLogin, setLogin] = useState(true)
|
|
const [cooldown, setCooldown] = useState(0)
|
|
|
|
function submit(data) {
|
|
if (!canLogin) return;
|
|
setError("");
|
|
setStatus("Loading..");
|
|
setLogin(false);
|
|
|
|
(async () => {
|
|
let {status, json} = await login(data.username.trim(), data.password.trim())
|
|
setCooldown(setTimeout(() => setLogin(true), 1000));
|
|
|
|
if (status !== 200) {
|
|
setStatus("Sign In")
|
|
return setError(json.reason)
|
|
}
|
|
|
|
toast.success("You have been logged in.")
|
|
window.localStorage.setItem("authtoken", json.token)
|
|
authDispatch({response: {token: json.token}})
|
|
})()
|
|
|
|
}
|
|
|
|
useEffect(() => {
|
|
let loc = new URLSearchParams(props.location.search).get("return")
|
|
if (authState.loggedIn) props.history.push("/" + (loc ? loc : ""))
|
|
return () => clearTimeout(cooldown)
|
|
}, [props, authState, cooldown])
|
|
|
|
|
|
return <div className="w-screen h-screen overflow-x-hidden bg-cover bg-center flex items-center flex-col"
|
|
style={{backgroundImage: `url(${background})`}}>
|
|
<Navbar history={props.history}/>
|
|
|
|
<form className="mt-32 sm:w-96 w-full" onSubmit={handleSubmit(submit)}>
|
|
<div className="text-2xl w-full font-semibold block ">
|
|
<div className="rounded-t-md inline bg-gray-100 text-gray-700 px-5 py-2">Log In</div>
|
|
</div>
|
|
<div className="px-8 pt-6 pb-8 mb-4 px-12 rounded-md rounded-tl-none bg-gray-100">
|
|
{error &&
|
|
<div className="px-2 py-2 mb-8 bg-red-300 text-red-900 text-xs font-semibold border border-red-600 rounded">
|
|
{error}
|
|
</div>
|
|
}
|
|
|
|
<Input name="username" type="text" placeholder="Username or Email" errors={errors}
|
|
register={register({required: {value: true, message: "You must provide a username."}})}>Username</Input>
|
|
|
|
<Input name="password" type="password" placeholder="********" errors={errors}
|
|
register={register({required: {value: true, message: "You must provide a password."}})}>Password</Input>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<input className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 mr-2 rounded" type="submit"
|
|
value={status}/>
|
|
<Link to="/reset" className="inline-block align-baseline font-bold text-sm text-blue-500 hover:text-blue-800">
|
|
Reset Password
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>;
|
|
}
|
|
|
|
export default Login;
|
|
|