Commit 5f4fcedc by dliangx

login page impl

parent e25eeeae
import { useRef, useState } from "react";
import { Back, ForwardArrow } from "../common/Icon";
const Login = () => {
const [loginName, setLoginName] = useState("");
const [loginPass, setLoginPass] = useState("");
const [error, setError] = useState("");
const loginNameRef = useRef<HTMLInputElement>(null);
const loginPassRef = useRef<HTMLInputElement>(null);
const regexUsername = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$";
const regexPassword =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{6,18}$/;
const usernameRegexNotMatch =
"username consists of characters and numbers, and is between 5 and 16 in length";
const passwordRegexNotMatch =
"password starts with a letter, is between 6~18 in length, and can only contain letters, numbers ";
function regex_username_test(username: string) {
if (username != "" && !username.match(regexUsername)) {
setError(usernameRegexNotMatch);
} else {
setError("");
}
}
function regex_password_test(password: string) {
if (password != "" && !password.match(regexPassword)) {
setError(passwordRegexNotMatch);
} else {
setError("");
}
}
function handle_login(username: string, password: string) {
if (username == "") {
setError("please fill username ");
loginNameRef.current?.focus();
return;
}
if (!username.match(regexUsername)) {
setError(usernameRegexNotMatch);
loginNameRef.current?.focus();
return;
}
if (password == "") {
setError("please fill password");
loginPassRef.current?.focus();
return;
}
if (!password.match(regexPassword)) {
setError(passwordRegexNotMatch);
loginPassRef.current?.focus();
return;
}
login();
}
const login = () => {
const url = import.meta.env.VITE_API_URL + "/login";
const bodyStr = JSON.stringify({ name: loginName, password: loginPass });
fetch(url, {
method: "POST",
body: bodyStr,
headers: {
"content-type": "application/json",
},
})
.then(async (response) => {
const text = response.text();
if (response.ok) {
return text;
} else if (response.status == 400) {
console.log(response.status);
setError(await text);
return;
}
})
.then((data) => {
if (!!data) {
localStorage.setItem("username", loginName);
localStorage.setItem("user_token", data);
var now = new Date();
localStorage.setItem(
"expire_time",
new Date(
now.getTime() + 99 * 24 * 60 * 60 * 1000
).toLocaleDateString()
);
history.go(-1);
}
})
.catch((error) => {
console.error("Error:", error);
});
};
return (
<>
<div className="flex h-10 pt-2 pr-12 items-end w-full ">
<Back className=" ml-2 " onClick={() => history.go(-1)} />
</div>
<div className=" mt-20 ">
<div className="w-4/5 m-auto pb-4">
<div
className="text-center w-full mr-2 h-12 "
onClick={() => {
setError("");
}}
>
LOGIN
</div>
</div>
<div className="flex">
<input
placeholder="username"
type="text"
ref={loginNameRef}
value={loginName}
onChange={(e) => {
regex_username_test(e.target.value);
setLoginName(e.target.value);
}}
className="w-4/5 m-auto h-12 mb-4 bg-transparent p-2 border-b rounded-none border-gray-600 hover:border-gray-300 focus:outline-none "
autoFocus
></input>
</div>
<div className="flex ">
<div className=" relative w-4/5 m-auto place-items-end ">
<input
placeholder="password"
type="password"
ref={loginPassRef}
value={loginPass}
onChange={(e) => {
regex_password_test(e.target.value);
setLoginPass(e.target.value);
}}
className="w-full m-auto h-12 bg-transparent p-2 border-b rounded-none border-gray-600 hover:border-gray-300 focus:outline-none "
></input>
<ForwardArrow
className="absolute bottom-2 right-2 z-10 "
onClick={() => handle_login(loginName, loginPass)}
/>
</div>
</div>
{error != "" && (
<div className="mt-10 w-4/5 m-auto text-center text-orange-400">
{error}
</div>
)}
</div>
</>
);
};
export default Login;
import { useRef, useState } from "react";
import { Back, ForwardArrow } from "../common/Icon";
const Register = () => {
const [registerName, setRegisterName] = useState("");
const [registerPass, setRegisterPass] = useState("");
const [registerRep, setRegisterRep] = useState("");
const [error, setError] = useState("");
const registerNameRef = useRef<HTMLInputElement>(null);
const registerPassRef = useRef<HTMLInputElement>(null);
const registerRepRef = useRef<HTMLInputElement>(null);
const regexUsername = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$";
const regexPassword =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{6,18}$/;
const usernameRegexNotMatch =
"username consists of characters and numbers, and is between 5 and 16 in length";
const passwordRegexNotMatch =
"password starts with a letter, is between 6~18 in length, and can only contain letters, numbers ";
const passwordTwiceNotMatch = "the password entered twice is not the same";
function regex_username_test(username: string) {
if (username != "" && !username.match(regexUsername)) {
setError(usernameRegexNotMatch);
} else {
setError("");
}
}
function regex_password_test(password: string) {
if (password != "" && !password.match(regexPassword)) {
setError(passwordRegexNotMatch);
} else {
setError("");
}
}
function handle_register(
username: string,
password: string,
passwordRep: string
) {
if (username == "") {
setError("please fill username ");
registerNameRef.current?.focus();
return;
}
if (!username.match(regexUsername)) {
setError(usernameRegexNotMatch);
registerNameRef.current?.focus();
return;
}
if (password == "") {
setError("please fill password");
registerPassRef.current?.focus();
return;
}
if (!password.match(regexPassword)) {
setError(passwordRegexNotMatch);
registerPassRef.current?.focus();
return;
}
if (passwordRep == "") {
setError(passwordTwiceNotMatch);
registerRepRef.current?.focus();
return;
}
if (!passwordRep.match(regexPassword)) {
setError(passwordRegexNotMatch);
registerRepRef.current?.focus();
return;
}
if (password !== passwordRep) {
setError(passwordTwiceNotMatch);
return;
}
register();
}
const register = () => {
const url = import.meta.env.VITE_API_URL + "/register";
const bodyStr = JSON.stringify({
name: registerName,
password: registerPass,
});
fetch(url, {
method: "POST",
body: bodyStr,
headers: {
"content-type": "application/json",
},
})
.then((response) => response.text())
.then((data) => {
console.log(data);
if (data == "success") {
history.go(-1);
} else {
setError(data);
}
})
.catch((error) => {
console.error("Error:", error);
});
};
return (
<>
<div className="flex h-10 pt-2 pr-12 items-end w-full ">
<Back className=" ml-2 " onClick={() => history.go(-1)} />
</div>
<div className=" mt-20 ">
<div className="flex w-4/5 m-auto pb-4">
<div
className="text-center w-full ml-2 h-8"
onClick={() => {
setError("");
}}
>
REGISTER
</div>
</div>
<div className="flex">
<input
placeholder="username"
type="text"
ref={registerNameRef}
value={registerName}
onChange={(e) => {
regex_username_test(e.target.value);
setRegisterName(e.target.value);
}}
className="w-4/5 m-auto h-12 bg-transparent p-2 border-b rounded-none border-gray-600 hover:border-gray-300 focus:outline-none "
autoFocus
></input>
</div>
<div className="flex ">
<div className=" relative w-4/5 m-auto place-items-end ">
<input
placeholder="password"
type="password"
ref={registerPassRef}
value={registerPass}
onChange={(e) => {
regex_password_test(e.target.value);
setRegisterPass(e.target.value);
}}
className="w-full m-auto h-12 bg-transparent p-2 border-b rounded-none border-gray-600 hover:border-gray-300 focus:outline-none "
></input>
</div>
</div>
<div className="flex ">
<div className=" relative w-4/5 m-auto place-items-end ">
<input
placeholder="password"
type="password"
ref={registerRepRef}
value={registerRep}
onChange={(e) => {
regex_password_test(e.target.value);
setRegisterRep(e.target.value);
}}
className="w-full m-auto h-12 bg-transparent p-2 border-b rounded-none border-gray-600 hover:border-gray-300 focus:outline-none "
></input>
<ForwardArrow
className="absolute bottom-2 right-2 z-10 "
onClick={() =>
handle_register(registerName, registerPass, registerRep)
}
/>
</div>
</div>
{error != "" && (
<div className="mt-10 w-4/5 m-auto text-center text-orange-400">
{error}
</div>
)}
</div>
</>
);
};
export default Register;
import { Navigate, useLocation } from "react-router-dom";
const RequireAuth = ({ children }: { children: JSX.Element }) => {
const isUserLoggedIn = () => {
return !!localStorage.getItem("user_token");
};
let location = useLocation();
if (!isUserLoggedIn()) {
return <Navigate to="/login" state={{ from: location }} replace />;
} else {
const expire_time = localStorage.getItem("expire_time");
if (expire_time != null) {
if (new Date(expire_time) < new Date()) {
localStorage.removeItem("user_token");
localStorage.removeItem("expire_time");
return <Navigate to="/login" state={{ from: location }} replace />;
}
} else {
localStorage.removeItem("user_token");
localStorage.removeItem("expire_time");
return <Navigate to="/login" state={{ from: location }} replace />;
}
}
return children;
};
export default RequireAuth;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment