login page
This commit is contained in:
parent
c509761b9b
commit
6e13bad6cb
File diff suppressed because it is too large
Load Diff
|
|
@ -10,7 +10,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"node-sass": "^7.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.3.0"
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@vitejs/plugin-react": "^2.0.1",
|
||||
"sass": "^1.54.8",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^3.0.7"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
17
src/App.tsx
17
src/App.tsx
|
|
@ -1,5 +1,20 @@
|
|||
// Modules
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
|
||||
// Style
|
||||
import "./assets/styles/style.scss";
|
||||
|
||||
// Pages
|
||||
import Login from "./pages/Login";
|
||||
|
||||
const App = () => {
|
||||
return <div className="App"></div>;
|
||||
return (
|
||||
<div className="App">
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
|
||||
|
||||
* {
|
||||
font-family: "Montserrat", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
padding: 0 5rem;
|
||||
max-width: 150rem;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f1f4f8;
|
||||
}
|
||||
|
||||
body,
|
||||
#root,
|
||||
.App {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
background: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@mixin transition-std {
|
||||
transition: 0.3s all ease;
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
.login {
|
||||
height: 100%;
|
||||
&.inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2.4rem;
|
||||
}
|
||||
|
||||
&__header {
|
||||
text-align: center;
|
||||
font-size: 2.8rem;
|
||||
}
|
||||
|
||||
&__form {
|
||||
min-width: 35rem;
|
||||
background: #fff;
|
||||
padding: 3.5rem;
|
||||
border: 1px solid #d9e2ef;
|
||||
border-radius: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.6rem;
|
||||
|
||||
&__error {
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
color: red;
|
||||
font-size: 1.4rem;
|
||||
font-weight: bold;
|
||||
@include transition-std;
|
||||
|
||||
&.active {
|
||||
@include transition-std;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__button {
|
||||
border-radius: 0.2rem;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
padding: 0.6rem 1.2rem;
|
||||
color: #fff;
|
||||
font-size: 1.6rem;
|
||||
|
||||
&--violet {
|
||||
background-color: #7c69ef;
|
||||
border: 0.1rem solid #7c69ef;
|
||||
@include transition-std;
|
||||
|
||||
&:hover {
|
||||
@include transition-std;
|
||||
background-color: #705ed6;
|
||||
border: 0.1rem solid #705ed6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8rem;
|
||||
|
||||
label {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
input {
|
||||
padding: 0.6rem 1.2rem;
|
||||
border: 1px solid #d9e2ef;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
&--check {
|
||||
label {
|
||||
font-size: 1.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@import "./general";
|
||||
@import "./login";
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
import React from "react";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
|
||||
const Login = () => {
|
||||
const cred: Record<string, string> = {
|
||||
username: "admin@2022",
|
||||
password: "backpackadmin",
|
||||
};
|
||||
const [valid, setValid] = useState({
|
||||
username: "",
|
||||
password: "",
|
||||
check: false,
|
||||
valid: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (valid.username === cred.username && valid.password === cred.password) {
|
||||
setValid({ ...valid, valid: true });
|
||||
} else {
|
||||
setValid({ ...valid, valid: false });
|
||||
}
|
||||
}, [valid.username, valid.password]);
|
||||
|
||||
return (
|
||||
<main className="login">
|
||||
<div className="container">
|
||||
<div className="login inner">
|
||||
<div className="login__wrapper">
|
||||
<h1 className="login__header">Login</h1>
|
||||
<form
|
||||
className="login__form"
|
||||
onSubmit={(e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<div className="login__form__block">
|
||||
<label htmlFor="username">Username</label>
|
||||
<input
|
||||
required
|
||||
autoComplete="true"
|
||||
type="text"
|
||||
id="username"
|
||||
placeholder="username"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setValid({ ...valid, username: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="login__form__block">
|
||||
<label htmlFor="password">Password</label>
|
||||
<input
|
||||
required
|
||||
autoComplete="true"
|
||||
type="password"
|
||||
id="password"
|
||||
placeholder="password"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setValid({ ...valid, password: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="login__form__block--check">
|
||||
<label>
|
||||
<input type="checkbox" name="remember" id="remember" />
|
||||
<span>Remember me</span>
|
||||
</label>
|
||||
</div>
|
||||
<span
|
||||
className={
|
||||
valid.check && !valid.valid
|
||||
? "login__form__error active"
|
||||
: "login__form__error"
|
||||
}
|
||||
>
|
||||
Invalid credentials
|
||||
</span>
|
||||
<button
|
||||
className="login__form__button login__form__button--violet"
|
||||
onClick={(e: React.FormEvent<HTMLButtonElement>) => {
|
||||
setValid({ ...valid, check: true });
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
Loading…
Reference in New Issue