init project

main
alex 2023-04-16 23:09:45 +02:00
parent cf20b75847
commit 29f53b0ee0
14 changed files with 1280 additions and 63 deletions

1024
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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"
}
} }
} }

View File

@ -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;
} }

View File

@ -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>
); );
} }

View File

@ -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();

View File

@ -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>
*/

View File

@ -0,0 +1,10 @@
import AppRoutes from "../AppRoutes";
function PageContent() {
return (
<div className="PageContent">
<AppRoutes />
</div>
);
}
export default PageContent;

View File

@ -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;

View File

@ -0,0 +1,7 @@
import { Button } from "antd";
function Dashboard() {
return <Button>Test</Button>;
}
export default Dashboard;

49
src/Pages/Login/index.js Normal file
View File

@ -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,
};

View File

@ -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;
} }

View File

@ -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();

View File

@ -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);

View File

@ -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";