login
parent
714dd8b919
commit
5b6fb4eb3e
|
@ -13,6 +13,7 @@
|
|||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"antd": "^5.4.2",
|
||||
"buffer": "^6.0.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-qr-scanner": "^1.0.0-alpha.11",
|
||||
|
@ -5635,6 +5636,25 @@
|
|||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/batch": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||
|
@ -5806,6 +5826,29 @@
|
|||
"node-int64": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
|
@ -9239,6 +9282,25 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"antd": "^5.4.2",
|
||||
"buffer": "^6.0.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-qr-scanner": "^1.0.0-alpha.11",
|
||||
|
|
|
@ -29,15 +29,5 @@
|
|||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
55
src/App.css
55
src/App.css
|
@ -1,30 +1,3 @@
|
|||
/*.App {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
} */
|
||||
|
||||
/*
|
||||
.SideMenuAndPageContent {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
/*background-color: rgba(0, 0, 0, 0.05);*/ /*
|
||||
min-height: 100vh;
|
||||
} */
|
||||
|
||||
/* SideMenu */
|
||||
/*.SideMenu {
|
||||
height: 100vh;
|
||||
/*background-color: #fff;*/ /*
|
||||
} */
|
||||
/*
|
||||
.SideMenuVertical {
|
||||
height: 100%;
|
||||
} */
|
||||
|
||||
.CompanyName {
|
||||
padding: 12px 12px 0 12px;
|
||||
color: #e67e22;
|
||||
|
@ -41,31 +14,3 @@
|
|||
font-size: 14px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
/* PageContent */
|
||||
/*.PageContent {
|
||||
padding: 12px;
|
||||
width: 100%;
|
||||
} */
|
||||
|
||||
/* Login */
|
||||
.login {
|
||||
position: fixed; /* Stay in place */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: rgb(0, 0, 0); /* Fallback color */
|
||||
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.login-content {
|
||||
background-color: #fefefe;
|
||||
margin: 5% auto 15% auto; /* 5% from the top, 15% from the bottom and centered */
|
||||
border: 1px solid #888;
|
||||
width: 80%; /* Could be more or less, depending on screen size */
|
||||
padding: 24px 24px 0 24px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
|
39
src/App.js
39
src/App.js
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "antd/dist/reset.css";
|
||||
import "./App.css";
|
||||
import PageContent from "./Components/PageContent";
|
||||
|
@ -6,20 +6,41 @@ import SideMenu from "./Components/SideMenu";
|
|||
import Login from "./Pages/Login";
|
||||
import { Layout } from "antd";
|
||||
|
||||
function useUserSession() {
|
||||
const getUserSession = () => {
|
||||
return JSON.parse(localStorage.getItem("session"));
|
||||
};
|
||||
|
||||
const [userSession, setUserSession] = useState(getUserSession());
|
||||
|
||||
const saveUserSession = (session) => {
|
||||
setUserSession(session);
|
||||
|
||||
if (session === undefined) {
|
||||
localStorage.removeItem("session");
|
||||
} else {
|
||||
localStorage.setItem("session", JSON.stringify(session));
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
setUserSession: saveUserSession,
|
||||
userSession,
|
||||
};
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [loggedIn, setLoggedIn] = useState(false);
|
||||
const { userSession, setUserSession } = useUserSession();
|
||||
|
||||
if (!userSession) {
|
||||
return <Login setUserSession={setUserSession} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{loggedIn ? (
|
||||
<Layout style={{ minHeight: "100vh" }}>
|
||||
<SideMenu setLoggedIn={setLoggedIn}></SideMenu>
|
||||
<SideMenu setUserSession={setUserSession}></SideMenu>
|
||||
<PageContent></PageContent>
|
||||
</Layout>
|
||||
) : (
|
||||
<Login setLoggedIn={setLoggedIn} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { useEffect, useState } from "react";
|
|||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default function SideMenu({ setLoggedIn }) {
|
||||
export default function SideMenu({ setUserSession }) {
|
||||
const location = useLocation();
|
||||
const [selectedKeys, setSelectedKeys] = useState("/");
|
||||
|
||||
|
@ -66,7 +66,7 @@ export default function SideMenu({ setLoggedIn }) {
|
|||
{
|
||||
label: "Logout",
|
||||
icon: <LogoutOutlined />,
|
||||
onClick: () => setLoggedIn(false),
|
||||
onClick: () => setUserSession(),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
@ -77,5 +77,5 @@ export default function SideMenu({ setLoggedIn }) {
|
|||
}
|
||||
|
||||
SideMenu.propTypes = {
|
||||
setLoggedIn: PropTypes.func.isRequired,
|
||||
setUserSession: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -1,16 +1,60 @@
|
|||
import { LockOutlined, LoginOutlined, UserOutlined } from "@ant-design/icons";
|
||||
import { Button, Form, Input } from "antd";
|
||||
import { Button, Form, Input, Modal } from "antd";
|
||||
import PropTypes from "prop-types";
|
||||
import config from "../../constants";
|
||||
import { useState } from "react";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
export default function Login({ setUserSession }) {
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handleSubmit = () => {
|
||||
fetch(config.API_ADDRESS + "/user/auth/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
password: Buffer.from(password).toString("base64"),
|
||||
}),
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
return Promise.reject(res.status);
|
||||
})
|
||||
.then((data) => setUserSession(data.Session))
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
export default function Login({ setLoggedIn }) {
|
||||
return (
|
||||
<>
|
||||
<div className="login">
|
||||
<Form className="login-content">
|
||||
<Modal
|
||||
title="Login"
|
||||
open={true}
|
||||
closable={false}
|
||||
centered
|
||||
keyboard={false}
|
||||
footer={
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
icon={<LoginOutlined />}
|
||||
className="login-form-button"
|
||||
onClick={() => handleSubmit()}
|
||||
>
|
||||
Log in
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<Form>
|
||||
<Form.Item name="username">
|
||||
<Input
|
||||
prefix={<UserOutlined className="site-form-item-icon" />}
|
||||
placeholder="Username"
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
|
@ -26,25 +70,15 @@ export default function Login({ setLoggedIn }) {
|
|||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
icon={<LoginOutlined />}
|
||||
className="login-form-button"
|
||||
onClick={() => setLoggedIn(true)}
|
||||
>
|
||||
Log in
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Login.propTypes = {
|
||||
setLoggedIn: PropTypes.func.isRequired,
|
||||
setUserSession: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
const config = {
|
||||
API_ADDRESS: "http://localhost:8080/v1",
|
||||
};
|
||||
|
||||
export default config;
|
Loading…
Reference in New Issue