init project
parent
cf20b75847
commit
29f53b0ee0
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
|
@ -3,11 +3,15 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ant-design/icons": "^5.0.1",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
"antd": "^5.4.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-qr-scanner": "^1.0.0-alpha.11",
|
||||||
|
"react-router-dom": "^6.10.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
|
@ -34,5 +38,11 @@
|
||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"react-qr-reader": {
|
||||||
|
"react": "$react",
|
||||||
|
"react-dom": "$react-dom"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
96
src/App.css
96
src/App.css
|
@ -1,38 +1,78 @@
|
||||||
.App {
|
.App {
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
width: 100vw;
|
||||||
justify-content: center;
|
height: 100vh;
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.App-link {
|
.SideMenuAndPageContent {
|
||||||
color: #61dafb;
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes App-logo-spin {
|
/* SideMenu */
|
||||||
from {
|
.SideMenu {
|
||||||
transform: rotate(0deg);
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
to {
|
/*
|
||||||
transform: rotate(360deg);
|
.SideMenuVertical {
|
||||||
|
height: 100%;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.SideMenu .CompanyName {
|
||||||
|
padding: 12px 12px 0 12px;
|
||||||
|
color: #e67e22;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.SideMenu .Subtitle {
|
||||||
|
text-align: center;
|
||||||
|
color: #9b59b6;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PageContent */
|
||||||
|
.PageContent {
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CameraScan */
|
||||||
|
.CameraScan button {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
-ms-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
32
src/App.js
32
src/App.js
|
@ -1,23 +1,23 @@
|
||||||
import logo from './logo.svg';
|
import React, { useState } from "react";
|
||||||
import './App.css';
|
import "antd/dist/reset.css";
|
||||||
|
import "./App.css";
|
||||||
|
import PageContent from "./Components/PageContent";
|
||||||
|
import SideMenu from "./Components/SideMenu";
|
||||||
|
import Login from "./Pages/Login";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const [loggedIn, setLoggedIn] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header className="App-header">
|
{loggedIn ? (
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
<div className="SideMenuAndPageContent">
|
||||||
<p>
|
<SideMenu></SideMenu>
|
||||||
Edit <code>src/App.js</code> and save to reload.
|
<PageContent></PageContent>
|
||||||
</p>
|
</div>
|
||||||
<a
|
) : (
|
||||||
className="App-link"
|
<Login setLoggedIn={setLoggedIn} />
|
||||||
href="https://reactjs.org"
|
)}
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Learn React
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from "@testing-library/react";
|
||||||
import App from './App';
|
import App from "./App";
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
test("renders learn react link", () => {
|
||||||
render(<App />);
|
render(<App />);
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
const linkElement = screen.getByText(/learn react/i);
|
||||||
expect(linkElement).toBeInTheDocument();
|
expect(linkElement).toBeInTheDocument();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Route, Routes } from "react-router-dom";
|
||||||
|
import Dashboard from "../../Pages/Dashboard";
|
||||||
|
|
||||||
|
function AppRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<Dashboard />}></Route>
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default AppRoutes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
<Route path="/inventory" element={<Inventory />}></Route>
|
||||||
|
<Route path="/orders" element={<Orders />}></Route>
|
||||||
|
<Route path="/customers" element={<Customers />}></Route>
|
||||||
|
*/
|
|
@ -0,0 +1,10 @@
|
||||||
|
import AppRoutes from "../AppRoutes";
|
||||||
|
|
||||||
|
function PageContent() {
|
||||||
|
return (
|
||||||
|
<div className="PageContent">
|
||||||
|
<AppRoutes />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default PageContent;
|
|
@ -0,0 +1,57 @@
|
||||||
|
import {
|
||||||
|
AppstoreOutlined,
|
||||||
|
CameraOutlined,
|
||||||
|
ShoppingCartOutlined,
|
||||||
|
UserOutlined,
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
import { Menu } from "antd";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
function SideMenu() {
|
||||||
|
const location = useLocation();
|
||||||
|
const [selectedKeys, setSelectedKeys] = useState("/");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const pathName = location.pathname;
|
||||||
|
setSelectedKeys(pathName);
|
||||||
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div className="SideMenu">
|
||||||
|
<div className="CompanyName">JANEX</div>
|
||||||
|
<div className="Subtitle">Admin-Dashboard</div>
|
||||||
|
<Menu
|
||||||
|
mode="vertical"
|
||||||
|
onClick={(item) => {
|
||||||
|
navigate(item.key);
|
||||||
|
}}
|
||||||
|
selectedKeys={[selectedKeys]}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: "Dashboard",
|
||||||
|
icon: <AppstoreOutlined />,
|
||||||
|
key: "/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Camera Scan",
|
||||||
|
icon: <CameraOutlined />,
|
||||||
|
key: "/camera-scan",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Orders",
|
||||||
|
icon: <ShoppingCartOutlined />,
|
||||||
|
key: "/orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Customers",
|
||||||
|
icon: <UserOutlined />,
|
||||||
|
key: "/customers",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
></Menu>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default SideMenu;
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { Button } from "antd";
|
||||||
|
|
||||||
|
function Dashboard() {
|
||||||
|
return <Button>Test</Button>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Dashboard;
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { LockOutlined, UserOutlined } from "@ant-design/icons";
|
||||||
|
import { Button, Form, Input } from "antd";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
|
export default function Login({ setLoggedIn }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="login">
|
||||||
|
<Form className="login-content">
|
||||||
|
<Form.Item name="username">
|
||||||
|
<Input
|
||||||
|
prefix={<UserOutlined className="site-form-item-icon" />}
|
||||||
|
placeholder="Username"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="password"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "Please input your Password!",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||||
|
type="password"
|
||||||
|
placeholder="Password"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
htmlType="submit"
|
||||||
|
className="login-form-button"
|
||||||
|
onClick={() => setLoggedIn(true)}
|
||||||
|
>
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Login.propTypes = {
|
||||||
|
setLoggedIn: PropTypes.func.isRequired,
|
||||||
|
};
|
|
@ -1,13 +1,13 @@
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
sans-serif;
|
sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
17
src/index.js
17
src/index.js
|
@ -1,17 +1,20 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from "react-dom/client";
|
||||||
import './index.css';
|
import "./index.css";
|
||||||
import App from './App';
|
import App from "./App";
|
||||||
import reportWebVitals from './reportWebVitals';
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
//import reportWebVitals from './reportWebVitals';
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
// to log results (for example: reportWebVitals(console.log))
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||||
reportWebVitals();
|
//reportWebVitals();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const reportWebVitals = onPerfEntry => {
|
const reportWebVitals = (onPerfEntry) => {
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||||
getCLS(onPerfEntry);
|
getCLS(onPerfEntry);
|
||||||
getFID(onPerfEntry);
|
getFID(onPerfEntry);
|
||||||
getFCP(onPerfEntry);
|
getFCP(onPerfEntry);
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
// allows you to do things like:
|
// allows you to do things like:
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
// expect(element).toHaveTextContent(/react/i)
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
// learn more: https://github.com/testing-library/jest-dom
|
||||||
import '@testing-library/jest-dom';
|
import "@testing-library/jest-dom";
|
||||||
|
|
Loading…
Reference in New Issue