Переглянути джерело

02 feat: 上传react网页

Chunxian Zhang 2 роки тому
джерело
коміт
671985dbd9
45 змінених файлів з 40079 додано та 1 видалено
  1. +2
    -1
      .gitignore
  2. +23
    -0
      web/.gitignore
  3. +70
    -0
      web/README.md
  4. +27847
    -0
      web/package-lock.json
  5. +46
    -0
      web/package.json
  6. BIN
      web/public/favicon.ico
  7. +43
    -0
      web/public/index.html
  8. BIN
      web/public/logo192.png
  9. BIN
      web/public/logo512.png
  10. +25
    -0
      web/public/manifest.json
  11. +3
    -0
      web/public/robots.txt
  12. +19
    -0
      web/src/App.js
  13. BIN
      web/src/assets/apple.png
  14. BIN
      web/src/assets/avatar.jpg
  15. BIN
      web/src/assets/avatar.png
  16. BIN
      web/src/assets/chrome.png
  17. +1
    -0
      web/src/assets/game.svg
  18. +1
    -0
      web/src/assets/life.svg
  19. BIN
      web/src/assets/logo-modified.png
  20. +1
    -0
      web/src/assets/study.svg
  21. +1
    -0
      web/src/assets/work.svg
  22. +1
    -0
      web/src/assets/时钟 (1).svg
  23. +1
    -0
      web/src/assets/时钟 (2).svg
  24. +1
    -0
      web/src/assets/时钟 (3).svg
  25. +1
    -0
      web/src/assets/时钟 (4).svg
  26. +1
    -0
      web/src/assets/时钟 (5).svg
  27. BIN
      web/src/assets/时钟.png
  28. +1
    -0
      web/src/assets/时钟.svg
  29. +9
    -0
      web/src/components/Add.jsx
  30. +215
    -0
      web/src/components/Analytic.jsx
  31. +55
    -0
      web/src/components/Dashboard.jsx
  32. +92
    -0
      web/src/components/Navbar.jsx
  33. +137
    -0
      web/src/components/Orders.jsx
  34. +83
    -0
      web/src/components/Sales.jsx
  35. +9
    -0
      web/src/components/Shopping.jsx
  36. +216
    -0
      web/src/components/Sidebar.jsx
  37. +135
    -0
      web/src/components/Statistic.jsx
  38. +177
    -0
      web/src/components/echarts/Bar.jsx
  39. +188
    -0
      web/src/components/echarts/Bar2.jsx
  40. +167
    -0
      web/src/components/echarts/Gannt.jsx
  41. +235
    -0
      web/src/components/echarts/Pie.jsx
  42. +231
    -0
      web/src/components/overview/Description.jsx
  43. +28
    -0
      web/src/index.css
  44. +12
    -0
      web/src/index.js
  45. +10002
    -0
      web/yarn.lock

+ 2
- 1
.gitignore Переглянути файл

@ -1 +1,2 @@
webui
webui
node_modules

+ 23
- 0
web/.gitignore Переглянути файл

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

+ 70
- 0
web/README.md Переглянути файл

@ -0,0 +1,70 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)

+ 27847
- 0
web/package-lock.json
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 46
- 0
web/package.json Переглянути файл

@ -0,0 +1,46 @@
{
"name": "web",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.1.3",
"echarts": "^5.3.2",
"node-sass": "^7.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.0",
"recharts": "^2.1.9",
"scrollreveal": "^4.0.9",
"styled-components": "^5.3.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
web/public/favicon.ico Переглянути файл

Перед Після

+ 43
- 0
web/public/index.html Переглянути файл

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<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>

BIN
web/public/logo192.png Переглянути файл

Перед Після
Ширина: 192  |  Висота: 192  |  Розмір: 5.2 KiB

BIN
web/public/logo512.png Переглянути файл

Перед Після
Ширина: 512  |  Висота: 512  |  Розмір: 9.4 KiB

+ 25
- 0
web/public/manifest.json Переглянути файл

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

+ 3
- 0
web/public/robots.txt Переглянути файл

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

+ 19
- 0
web/src/App.js Переглянути файл

@ -0,0 +1,19 @@
import React from 'react'
import styled from 'styled-components'
import Sidebar from './components/Sidebar.jsx'
import Dashboard from './components/Dashboard.jsx'
function App() {
return (
<Div>
<Sidebar></Sidebar>
<Dashboard></Dashboard>
</Div>
)
}
export default App;
const Div = styled.div`
position: relative;
`

BIN
web/src/assets/apple.png Переглянути файл

Перед Після
Ширина: 1600  |  Висота: 1600  |  Розмір: 268 KiB

BIN
web/src/assets/avatar.jpg Переглянути файл

Перед Після
Ширина: 3648  |  Висота: 5472  |  Розмір: 1.2 MiB

BIN
web/src/assets/avatar.png Переглянути файл

Перед Після
Ширина: 230  |  Висота: 230  |  Розмір: 21 KiB

BIN
web/src/assets/chrome.png Переглянути файл

Перед Після
Ширина: 32  |  Висота: 32  |  Розмір: 1.4 KiB

+ 1
- 0
web/src/assets/game.svg
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
web/src/assets/life.svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649625494916" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6006" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M958.632223 565.06252c0-97.822956-73.257467-178.683589-167.754678-191.071733l0-22.175045c0.781806-6.213515 1.319042-12.501732 1.319042-18.924002 0-3.780093-0.741897-7.353478-1.817392-10.779507-5.116531-78.403674-70.363558-140.674926-150.042271-140.674926l-56.774051 0c-19.980054 0-36.169781 16.194844-36.169781 36.169781s16.188704 36.169781 36.169781 36.169781l56.774051 0c43.115983 0 78.202083 35.074843 78.202083 78.190827l0 14.907525c-6.628978 36.703947-38.759769 64.654532-77.354785 64.654532L216.386282 411.529751c-38.58683 0-70.710458-27.931143-77.354785-64.615647l0-14.94641c0-43.115983 35.07996-78.190827 78.196966-78.190827l44.658106 0c19.974937 0 36.169781-16.194844 36.169781-36.169781s-16.194844-36.169781-36.169781-36.169781l-44.658106 0c-79.672574 0-144.909367 62.261019-150.035108 140.655484-1.080611 3.431146-1.824555 7.011694-1.824555 10.79895 0 6.435573 0.538259 12.736069 1.324158 18.961864l0 403.245064c0 82.994226 67.528999 150.511969 150.535505 150.511969l423.107437 0c82.654488 0 149.919475-66.957994 150.488433-149.46922C885.34815 743.776807 958.632223 662.903895 958.632223 565.06252zM640.3359 833.273121 217.22744 833.273121c-43.115983 0-78.196966-35.068703-78.196966-78.17343L139.030473 462.319507c22.660092 13.588483 49.062416 21.550829 77.354785 21.550829l424.796916 0c28.291346 0 54.694693-7.962346 77.354785-21.552875l0 292.783253C718.537983 798.204417 683.451884 833.273121 640.3359 833.273121zM790.876522 682.947394 790.876522 447.178669c54.438866 11.604292 95.41614 60.031235 95.41614 117.883851S845.316411 671.342078 790.876522 682.947394z" p-id="6007"></path><path d="M345.481476 320.712349c-5.810333 11.979846-0.806365 26.403347 11.17962 32.219819 3.391237 1.642406 6.975878 2.419096 10.508331 2.419096 8.947789 0 17.543561-5.003967 21.711488-13.598716 1.483794-3.072989 36.063357-75.894528-2.202155-128.500653-19.09694-26.25599-1.74269-53.919027 0.400113-57.120952 7.476275-10.914584 4.756327-25.843598-6.122441-33.414017-10.961656-7.617491-25.961278-4.915963-33.567513 6.022157-1.636267 2.343371-39.542598 58.115606 0.294712 112.876814C365.273241 265.810948 352.038822 306.966277 345.481476 320.712349z" p-id="6008"></path><path d="M466.046389 320.712349c-5.804193 11.979846-0.800225 26.403347 11.17348 32.219819 3.391237 1.642406 6.982018 2.419096 10.514471 2.419096 8.947789 0 17.543561-5.003967 21.711488-13.598716 1.483794-3.072989 36.063357-75.894528-2.202155-128.500653-19.09694-26.25599-1.74269-53.919027 0.400113-57.120952 7.476275-10.914584 4.756327-25.843598-6.122441-33.414017-10.961656-7.617491-25.961278-4.915963-33.567513 6.022157-1.636267 2.343371-39.536458 58.115606 0.294712 112.876814C485.838154 265.810948 472.604758 306.966277 466.046389 320.712349z" p-id="6009"></path></svg>

BIN
web/src/assets/logo-modified.png Переглянути файл

Перед Після
Ширина: 186  |  Висота: 186  |  Розмір: 26 KiB

+ 1
- 0
web/src/assets/study.svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649625443236" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4127" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M704 170.666667a234.666667 234.666667 0 0 0-192 100.266666A234.666667 234.666667 0 0 0 85.333333 405.333333v411.306667a7.893333 7.893333 0 0 0 0 2.346667v2.773333a15.786667 15.786667 0 0 0 0 2.986667v1.28a12.586667 12.586667 0 0 0 1.28 2.986666v1.28l2.133334 2.986667v1.28l1.706666 1.92 1.493334 1.28v1.066667l1.92 1.493333 3.84 2.56h10.88l2.133333 1.28H143.573333l2.773334-1.493333h1.493333c6.826667-3.84 174.506667-93.44 342.613333 0h1.28a24.96 24.96 0 0 0 5.546667 2.133333H500.48a16.213333 16.213333 0 0 0 4.48 0H524.586667l4.48-1.92h1.92c6.826667-3.84 174.506667-93.44 342.613333 0h1.493333l6.826667 2.773333h2.56A37.12 37.12 0 0 0 896 853.333333a51.626667 51.626667 0 0 0 10.026667-1.28h2.56a42.666667 42.666667 0 0 0 7.253333-2.986666l1.493333-2.133334a37.12 37.12 0 0 0 8.106667-6.186666 36.693333 36.693333 0 0 0 5.973333-7.893334v-1.066666a7.68 7.68 0 0 1 0-1.92 25.386667 25.386667 0 0 0 1.706667-4.266667l1.28-3.84a22.613333 22.613333 0 0 0 0-4.053333 31.786667 31.786667 0 0 0 0-4.48V405.333333A234.666667 234.666667 0 0 0 704 170.666667zM170.666667 746.666667V405.333333a149.333333 149.333333 0 0 1 298.666666 0v339.413334A458.026667 458.026667 0 0 0 170.666667 746.666667z m384 0V405.333333a149.333333 149.333333 0 0 1 298.666666 0v339.413334A458.026667 458.026667 0 0 0 554.666667 746.666667z" p-id="4128"></path></svg>

+ 1
- 0
web/src/assets/work.svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649625412400" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2348" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M896 483.626667a42.666667 42.666667 0 0 0 42.666667-42.666667v-59.306667a90.88 90.88 0 0 0-1.706667-17.066666 97.493333 97.493333 0 0 0-5.12-15.786667 106.666667 106.666667 0 0 0-8.106667-14.293333 112.426667 112.426667 0 0 0-10.453333-12.16 95.146667 95.146667 0 0 0-26.88-17.493334 85.333333 85.333333 0 0 0-15.573333-4.48A88.106667 88.106667 0 0 0 853.333333 298.666667h-85.333333V146.986667A61.866667 61.866667 0 0 0 706.346667 85.333333H317.653333A61.866667 61.866667 0 0 0 256 146.986667V298.666667H170.666667a84.053333 84.053333 0 0 0-16.426667 1.706666 75.733333 75.733333 0 0 0-16 4.693334 83.2 83.2 0 0 0-14.293333 7.466666 92.586667 92.586667 0 0 0-12.586667 10.026667 96.213333 96.213333 0 0 0-10.24 12.16 76.373333 76.373333 0 0 0-7.893333 14.08 80.853333 80.853333 0 0 0-5.333334 15.786667 90.88 90.88 0 0 0-1.706666 17.066666v474.026667a90.88 90.88 0 0 0 1.706666 17.066667 97.493333 97.493333 0 0 0 5.12 15.786666 106.666667 106.666667 0 0 0 8.106667 14.293334 112.426667 112.426667 0 0 0 10.453333 12.16 82.56 82.56 0 0 0 12.586667 9.813333 83.413333 83.413333 0 0 0 14.293333 7.68 85.333333 85.333333 0 0 0 15.573334 4.48A88.106667 88.106667 0 0 0 170.666667 938.666667h682.666666a84.053333 84.053333 0 0 0 16.426667-1.706667 75.733333 75.733333 0 0 0 16-4.693333 83.2 83.2 0 0 0 14.293333-7.466667 92.586667 92.586667 0 0 0 12.586667-10.026667 96.213333 96.213333 0 0 0 10.24-12.16 76.373333 76.373333 0 0 0 7.893333-14.08 80.853333 80.853333 0 0 0 5.333334-15.786666 90.88 90.88 0 0 0 1.706666-17.066667V618.666667a42.666667 42.666667 0 0 0-85.333333 0v234.666666H170.666667V384h682.666666v57.173333a42.666667 42.666667 0 0 0 42.666667 42.453334zM341.333333 170.666667h341.333334v128H341.333333z" fill="#333333" p-id="2349"></path><path d="M298.666667 576a42.666667 42.666667 0 0 0 0 85.333333h426.666666a42.666667 42.666667 0 0 0 0-85.333333z" fill="#333333" p-id="2350"></path></svg>

+ 1
- 0
web/src/assets/时钟 (1).svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649628962903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3857" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="3858" fill="#f4ea2a"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="3859" fill="#f4ea2a"></path></svg>

+ 1
- 0
web/src/assets/时钟 (2).svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649628962903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3857" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="3858" fill="#1afa29"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="3859" fill="#1afa29"></path></svg>

+ 1
- 0
web/src/assets/时钟 (3).svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649628962903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3857" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="3858" fill="#1296db"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="3859" fill="#1296db"></path></svg>

+ 1
- 0
web/src/assets/时钟 (4).svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649629049893" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5832" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="5833" fill="#13227a"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="5834" fill="#13227a"></path></svg>

+ 1
- 0
web/src/assets/时钟 (5).svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649629049893" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5832" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="5833" fill="#dbdbdb"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="5834" fill="#dbdbdb"></path></svg>

BIN
web/src/assets/时钟.png Переглянути файл

Перед Після
Ширина: 32  |  Висота: 32  |  Розмір: 950 B

+ 1
- 0
web/src/assets/时钟.svg Переглянути файл

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1649628962903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3857" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z" p-id="3858" fill="#d81e06"></path><path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z" p-id="3859" fill="#d81e06"></path></svg>

+ 9
- 0
web/src/components/Add.jsx Переглянути файл

@ -0,0 +1,9 @@
import React from 'react'
function Add() {
return (
<div>Add</div>
)
}
export default Add

+ 215
- 0
web/src/components/Analytic.jsx Переглянути файл

@ -0,0 +1,215 @@
import React from 'react'
import styled from 'styled-components'
import { AreaChart, Area, Tooltip, ResponsiveContainer } from "recharts"
const data = [
{ data: 4500 },
{
data: 5000,
},
{
data: 4700,
},
{
data: 4400,
},
{
data: 4800,
},
{
data: 5300,
},
{
data: 5800,
},
{
data: 6000,
},
{
data: 6300,
},
{
data: 6580,
},
{
data: 6780,
},
{
data: 6680,
},
{
data: 6500,
},
{
data: 6300,
},
{
data: 5900,
},
{
data: 5700,
},
{
data: 5500,
},
{
data: 5300,
},
{
data: 5100,
},
{
data: 5090,
},
{
data: 5300,
},
{
data: 5800,
},
{
data: 6000,
},
{
data: 6300,
},
{
data: 6780,
},
{
data: 6500,
},
{
data: 6300,
},
{
data: 6500,
},
{
data: 6700,
},
{
data: 7000,
},
{
data: 7300,
},
{
data: 7500,
},
{
data: 7700,
},
{
data: 8090,
},
{
data: 8190,
},
{
data: 7990,
},
{
data: 7700,
},
{
data: 7500,
},
{
data: 7300,
},
{
data: 7000,
},
{
data: 6700,
},
{
data: 6500,
},
{
data: 6300,
},
{
data: 6500,
},
{
data: 6780,
},
{
data: 6300,
},
{
data: 6000,
},
{
data: 5800,
},
{
data: 5490,
},
{
data: 6000,
},
{
data: 8000,
},
];
function Analytic() {
return (
<Section>
<div className="analytics">
<div className="analytics__details">
<div>
<h4>Sales Analytics</h4>
</div>
<div>
<button>Switch to weekly</button>
</div>
</div>
<div className="analytics__graph">
</div>
</div>
</Section>
)
}
export default Analytic
const Section = styled.section`
.analytics {
color: black;
width: 100%;
.analytics__details {
display: flex;
justify-content: space-between;
margin: 1rem 0;
div {
display: flex;
gap: 1rem;
button: {
border-radius: 0.5rem;
padding: 0.4rem 1rem;
border: none;
cursor: pointer;
background-color: #EEF4FF;
color: black;
}
}
}
}
.analytics__graph {
height: 10rem;
width: 100%;
.recharts-default-tooltip {
background-color: black !important;
border-color: black !important;
color: white !important;
}
}
`

+ 55
- 0
web/src/components/Dashboard.jsx Переглянути файл

@ -0,0 +1,55 @@
import React from 'react'
import styled from 'styled-components'
import Navbar from './Navbar'
import Sales from './Sales'
import Orders from './Orders'
import Description from './overview/Description.jsx'
import {
BrowserRouter as Router,
Route, Routes,
Link,
} from 'react-router-dom'
function Dashboard() {
return (
<Section>
<Navbar></Navbar>
{/* <div className="grid">
<div className="grid_1">
<Sales></Sales>
<Orders></Orders>
</div>
</div> */}
<Description></Description>
</Section>
)
}
export default Dashboard
const Section = styled.section`
margin-left: 15vw;
padding: 2rem;
height: 100%;
.grid {
display: grid;
grid-template-columns: 92% 8%;
gap: 2rem;
margin-top: 1rem;
.grid_1 {
z-index: 2;
width: 100%;
display: flex;
flex-direction: column;
gap: 1rem;
}
.grid_2 {
z-index: 2;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
}
`;

+ 92
- 0
web/src/components/Navbar.jsx Переглянути файл

@ -0,0 +1,92 @@
import React from 'react'
import styled from 'styled-components'
import { BiSearch } from "react-icons/bi"
import { AiOutlineCalendar } from "react-icons/ai"
import { AiOutlineBell } from "react-icons/ai"
import { AiOutlineCaretDown } from "react-icons/ai"
import avatarImage from "../assets/avatar.png"
function Navbar() {
return (
<Nav>
<div className="title">
<h1>面板</h1>
</div>
<div className="notification">
<div className="date">
<AiOutlineCalendar></AiOutlineCalendar>
<span>Apr 11, 2022</span>
</div>
<div className="icon">
<BiSearch></BiSearch>
<span>|</span>
<AiOutlineBell></AiOutlineBell>
<span>|</span>
<div className="image">
<img src={avatarImage} alt="" />
</div>
<AiOutlineCaretDown></AiOutlineCaretDown>
</div>
</div>
</Nav>
)
}
export default Navbar
const Nav = styled.nav`
display: flex;
justify-content: space-between;
color: white;
.title {
h1 {
margin-left: 1rem;
color: black;
font-weight: bold;
font-size: 2rem;
margin-top: 1rem;
}
}
.notification {
display: flex;
align-items: center;
margin-top: -10px;
.date {
background-color: #F8F9FE;
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
border-radius: 1rem;
svg {
color: black;
}
span {
color: black;
}
}
.icon {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
svg {
color: black;
}
span {
color: black;
}
.image {
display: flex;
gap: 1rem;
img {
height: 2.5rem;
width: 2.5rem;
border-radius: 3rem;
}
}
}
}
`

+ 137
- 0
web/src/components/Orders.jsx Переглянути файл

@ -0,0 +1,137 @@
import React from 'react'
import styled from 'styled-components'
import apple from '../assets/apple.png'
import chrome from '../assets/chrome.png'
function Orders() {
return (
<Section>
<div className="orders">
<div className="orders__details">
<div>
<h4>详细使用记录</h4>
</div>
<div>
<button>查看全部</button>
</div>
</div>
<div className="orders__table">
<table>
<tr>
<th>标题</th>
<th>应用</th>
<th>开始</th>
<th>结束</th>
<th>持续时间</th>
<th>标签</th>
</tr>
<tr>
<td>哔哩哔哩 (-)つロ 干杯~-bilibili</td>
<td className="img">
{' '}
<img src={chrome} alt="" />
<span>Google Chrome</span>
</td>
<td>8:38:28</td>
<td>8:41:23</td>
<td>
<button>0:02:55</button>
</td>
<td>娱乐</td>
</tr>
<tr>
<td>哔哩哔哩热门</td>
<td className="img">
{' '}
<img src={chrome} alt="" />
<span>Google Chrome</span>
</td>
<td>8:41:24</td>
<td>8:42:03</td>
<td>
<button>0:00:39</button>
</td>
<td>娱乐</td>
</tr>
<tr>
<td>哔哩哔哩入站必刷</td>
<td className="img">
{' '}
<img src={chrome} alt="" />
<span>Google Chrome</span>
</td>
<td>8:42:04</td>
<td>8:42:37</td>
<td>
<button>0:00:33</button>
</td>
<td>娱乐</td>
</tr>
</table>
</div>
</div>
</Section>
)
}
export default Orders
const Section = styled.section`
.orders {
color: black;
width: 100%;
.orders__details {
display: flex;
justify-content: space-between;
margin: 1rem 0;
div {
display: flex;
gap: 1rem;
button {
padding: 0.4rem 1rem;
border: none;
cursor: pointer;
background-color: white;
color: #668dff;
font-weight: bold;
}
}
}
.orders__table {
display: flex;
justify-content: space-between;
margin: 1rem 0;
table {
border-collapse: collapse;
width: 100%;
th,
td {
text-align: center;
padding: 5px;
justify-content: space-evenly;
button {
border-radius: 0.3rem;
padding: 0.4rem;
border: none;
cursor: pointer;
background-color: #eef4ff;
color: blue;
font-weight: bold;
}
img {
height: 2rem;
width: 2rem;
}
span {
margin-top: 0.2rem;
}
}
.img {
display: flex;
justify-content: center;
}
}
}
}
`

+ 83
- 0
web/src/components/Sales.jsx Переглянути файл

@ -0,0 +1,83 @@
import React from 'react'
import styled from 'styled-components'
import { AiOutlineCaretDown } from "react-icons/ai"
import Gannt from "./echarts/Gannt.jsx"
function Sales() {
return (
<Section>
<div className="sales">
<div className="sales__details">
<div>
<h4>使用记录总览</h4>
</div>
<div>
<button>
today
<AiOutlineCaretDown></AiOutlineCaretDown>
</button>
</div>
</div>
<div id="gantt">
<Gannt
data={[]}
dataCount={10}
startTime={0}
categories={['标签', '计算机使用', '应用']}
types={[
{ name: 'JS Heap', color: '#7b9ce1' },
{ name: 'Documents', color: '#bd6d6c' },
{ name: 'Nodes', color: '#75d874' },
{ name: 'Listeners', color: '#e0bc78' },
{ name: 'GPU Memory', color: '#dc77dc' },
{ name: 'GPU', color: '#72b362' }
]}
>
</Gannt>
</div>
</div>
</Section>
)
}
export default Sales
/* css部分 */
const Section = styled.section`
.sales {
color: black;
width: 100%;
.sales__details {
display: flex;
justify-content: space-between;
margin: 1rem 0;
div {
display: flex;
gap: 1rem;
button {
border-radius: 0.5rem;
padding: 0.4rem 1rem;
border: none;
cursor: pointer;
background-color: #EEF4FF;
color: black;
svg {
font-size: 0.6rem;
}
}
}
}
.sales__graph {
height: 10rem;
width: 100%;
.recharts-default-tooltip {
background-color: black !important;
border-color: black !important;
color: white !important;
}
}
}
`
/* js部分 */

+ 9
- 0
web/src/components/Shopping.jsx Переглянути файл

@ -0,0 +1,9 @@
import React from 'react'
function Shopping() {
return (
<div>Shopping</div>
)
}
export default Shopping

+ 216
- 0
web/src/components/Sidebar.jsx Переглянути файл

@ -0,0 +1,216 @@
import React, {useState, useEffect} from 'react'
import styled from 'styled-components'
import { AiOutlineAppstore } from "react-icons/ai";
import { AiOutlineShoppingCart } from "react-icons/ai";
import { AiOutlineShopping } from "react-icons/ai";
import { AiOutlineLogout } from "react-icons/ai";
import { AiOutlineMessage } from "react-icons/ai";
import { AiOutlinePieChart } from "react-icons/ai";
import { AiOutlineSetting } from "react-icons/ai";
import { AiOutlineUsergroupAdd } from "react-icons/ai";
import { AiFillCodeSandboxCircle } from "react-icons/ai";
import { SiAccusoft } from "react-icons/si";
import logo from "../assets/logo-modified.png"
function Sidebar() {
const [currentLink, setCurrentLink] = useState(1);
return (
<Section>
<div className="top">
<div className="brand">
<img src={logo} alt="" />
<span>懒人记时</span>
</div>
<div className="links">
<ul>
<li
className={currentLink === 1 ? "active" : "none"}
onClick={() => setCurrentLink(1)}
>
<a href="#">
<AiOutlineAppstore></AiOutlineAppstore>
<span className="border">面板</span>
</a>
</li>
<li
className={currentLink === 3 ? "active" : "none"}
onClick={() => setCurrentLink(3)}
>
<a href="#">
<AiOutlineShopping></AiOutlineShopping>
<span className="border">应用</span>
</a>
</li>
<li
className={currentLink === 5 ? "active" : "none"}
onClick={() => setCurrentLink(5)}
>
<a href="#">
<AiOutlinePieChart></AiOutlinePieChart>
<span className="border">总览</span>
</a>
</li>
<li
className={currentLink === 6 ? "active" : "none"}
onClick={() => setCurrentLink(6)}
>
<a href="#">
<AiOutlineMessage></AiOutlineMessage>
<span className="border">自定义</span>
</a>
</li>
<li
className={currentLink === 7 ? "active" : "none"}
onClick={() => setCurrentLink(7)}
>
<a href="#">
<AiOutlineSetting></AiOutlineSetting>
<span className="border">设置</span>
</a>
</li>
</ul>
</div>
</div>
<div className="logout">
<a href="#">
<AiOutlineLogout></AiOutlineLogout>
<span>登出</span>
</a>
</div>
</Section>
)
}
export default Sidebar
const Section = styled.section`
position: fixed;
left: 0;
background-color: #F8F9EF;
height: 100vh;
width: 15vw;
display: flex;
flex-direction: column; // 沿
align-items: center; //
justify-content: space-between;
padding: 2rem 0;
gap: 2rem;
.top {
display: flex;
flex-direction: column;
gap: 2rem;
width: 100%;
.brand {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
gap: 1.3rem 0;
img {
width: 2.5rem;
margin-right: 0.5rem;
}
svg {
color: blue;
font-size: 2rem;
}
span {
font-size: 1.5rem;
font-weight: bold;
color: black;
}
}
.links {
display: flex;
justify-content: center;
ul {
list-style-type: none;
display: flex;
flex-direction: column;
gap: 1rem;
li {
padding: 0.6rem 2rem;
border-radius: 0.3rem;
&:hover {
background-color: black;
a {
color: white;
}
}
a {
text-decoration: none;
display: flex;
gap: 1rem;
color: grey;
svg {
font-size: 1.4rem;
}
span {
display: flex;
gap: 1rem;
}
}
}
.active {
background-color: black;
a {
color: white;
}
}
}
}
}
.map {
width: 90%;
display: flex;
background-color: #EBECF1;
padding-top: 10px;
padding-bottom: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1rem;
margin-top: -25px;
border-radius: 0.5rem;
svg {
color: blue;
font-size: 2rem;
}
}
.logout {
padding: 0.6rem;
margin-left: -2rem;
a {
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
color: black;
gap: 1rem;
svg {
font-size: 1.4rem;
}
span {
display: flex;
}
}
}
`

+ 135
- 0
web/src/components/Statistic.jsx Переглянути файл

@ -0,0 +1,135 @@
import React from 'react'
import styled from 'styled-components'
import { AiFillTag } from "react-icons/ai";
import { AiFillExperiment } from "react-icons/ai";
import { AiFillDollarCircle } from "react-icons/ai";
import { AiOutlineArrowUp } from "react-icons/ai";
import { AiOutlineArrowDown } from "react-icons/ai";
function Statistic() {
return (
<Section>
<div className="analytic color1">
<div className="design">
<div className="logo">
<AiFillTag></AiFillTag>
</div>
<div className="content">
<h5>$123,456,789</h5>
</div>
</div>
<div className="total">
<h6>TOTAL SALES</h6>
<span className="t1">+18%</span>
<AiOutlineArrowUp className="svg1"></AiOutlineArrowUp>
</div>
</div>
<div className="analytic color2">
<div className="design">
<div className="logo">
<AiFillExperiment></AiFillExperiment>
</div>
<div className="content">
<h5>$123,456,789</h5>
</div>
</div>
<div className="total">
<h6>TOTAL EXPENSES</h6>
<span className="t2">-9%</span>
<AiOutlineArrowDown className="svg2"></AiOutlineArrowDown>
</div>
</div>
<div className="analytic color3">
<div className="design">
<div className="logo">
<AiFillExperiment></AiFillExperiment>
</div>
<div className="content">
<h5>$123,456,789</h5>
</div>
</div>
<div className="total">
<h6>TOTAL REVENUE</h6>
<span className="t1">+24%</span>
<AiOutlineArrowUp className="svg1"></AiOutlineArrowUp>
</div>
</div>
</Section>
)
}
export default Statistic
const Section = styled.section`
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
.color1 {
background-color: #EEF4FF;
}
.color2 {
background-color: #FDF4F5;
}
.color3 {
background-color: #FFFCE4;
}
.analytic {
padding: 1rem 2rem 1rem 2rem;
border-radius: 1rem;
color: black;
justify-content: space-evenly;
align-items: center;
gap: 1rem;
transition: 0.5s ease-in-out;
&:hover {
background-color: #D4e0ff;
color: black;
svg {
color: black;
}
}
.design {
display: flex;
align-items: center;
gap: 1rem;
.logo {
background-color: white;
border-radius: 1rem;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
padding: 1.5rem;
svg {
font-size: 1.5rem;
}
}
}
.total {
display: flex;
align-items: center;
gap: 1rem;
justify-content: space-evenly;
margin-top: 20px;
.svg1 {
color: green;
}
.svg2 {
color: red;
}
.t1 {
color: green;
}
.t2 {
color: red;
}
h6 {
color: grey;
}
}
}
`

+ 177
- 0
web/src/components/echarts/Bar.jsx Переглянути файл

@ -0,0 +1,177 @@
import React from 'react'
import * as echarts from 'echarts/core'
import { TitleComponent, TooltipComponent, GridComponent, DataZoomComponent } from 'echarts/components'
import { CustomChart } from 'echarts/charts'
import { BarChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers'
import { PictorialBarChart } from 'echarts/charts';
import styled from 'styled-components'
echarts.use([TitleComponent, TooltipComponent, GridComponent, DataZoomComponent, CustomChart, CanvasRenderer, PictorialBarChart, BarChart])
class Bar extends React.Component {
constructor(props) {
super(props)
}
componentDidMount() {
var myChart = echarts.init(document.getElementById('Bar'))
myChart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
show: false
},
grid: {
left: 0,
right: "5%",
containLabel:true
},
xAxis: {
show: false,
type: 'value'
},
yAxis: [{
type: 'category',
inverse: true,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisPointer: {
label: {
show: true,
margin: 30
}
},
data: this.props.datas.map(item => item.name),
axisLabel: {
margin: 100,
fontSize: 14,
align: 'left',
color: '#333',
rich: {
a1: {
color: '#fff',
backgroundColor: this.props.colorList[0],
width: 30,
height: 30,
align: 'center',
borderRadius: 2
},
a2: {
color: '#fff',
backgroundColor: this.props.colorList[1],
width: 30,
height: 30,
align: 'center',
borderRadius: 2
},
a3: {
color: '#fff',
backgroundColor: this.props.colorList[2],
width: 30,
height: 30,
align: 'center',
borderRadius: 2
},
b: {
color: '#fff',
backgroundColor: this.props.colorList[3],
width: 30,
height: 30,
align: 'center',
borderRadius: 2
}
},
formatter: (params) => {
var index = this.props.datas.map(item => item.name).indexOf(params);
index = index + 1;
if (index - 1 < 3) {
return [
'{a' + index + '|' + index + '}' + ' ' + params
].join('\n')
} else {
return [
'{b|' + index + '}' + ' ' + params
].join('\n')
}
}
}
}, {
type: 'category',
inverse: true,
axisTick: 'none',
axisLine: 'none',
show: true,
data: this.props.datas.map(item => item.value),
axisLabel: {
show:true,
fontSize: 14,
color: '#333',
formatter:'{value}%'
}
}],
series: [{
z: 2,
name: 'value',
type: 'bar',
barWidth: 20,
zlevel: 1,
data: this.props.datas.map((item, i) => {
let itemStyle = {
color: i > 3 ? this.props.colorList[3] : this.props.colorList[i]
}
return {
value: item.value,
itemStyle: itemStyle
};
}),
label: {
show: false,
position: 'right',
color: '#333333',
fontSize: 14,
offset: [10, 0]
}
},
{
name: '背景',
type: 'bar',
barWidth: 20,
barGap: '-100%',
itemStyle: {
normal: {
color: 'rgba(118, 111, 111, 0.55)'
}
},
data: this.props.maxArr,
}
]
})
}
render() {
return (
<Div id="Bar">
</Div>
)
}
}
const Div = styled.div`
width: 100%;
height: 50vh;
border-radius: 1rem;
background-color: #fffce4;
`
export default Bar

+ 188
- 0
web/src/components/echarts/Bar2.jsx Переглянути файл

@ -0,0 +1,188 @@
import React from 'react'
import * as echarts from 'echarts/core'
import { TitleComponent, TooltipComponent, GridComponent, DataZoomComponent } from 'echarts/components'
import { CustomChart } from 'echarts/charts'
import { BarChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers'
import { PictorialBarChart } from 'echarts/charts';
import styled from 'styled-components'
echarts.use([TitleComponent, TooltipComponent, GridComponent, DataZoomComponent, CustomChart, CanvasRenderer, PictorialBarChart, BarChart])
class Bar2 extends React.Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.props.data.map((a, b) => {
this.props.xData.push(a.name);
if (a.value === 0) {
this.props.yData.push(a.value + this.props.min);
} else {
this.props.yData.push(a.value);
}
});
var myChart = echarts.init(document.getElementById('Bar2'))
myChart.setOption({
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
opacity: 0
}
},
formatter: (prams) => {
if (prams[0].data === this.props.min) {
return "屏幕使用率:0%"
} else {
return "屏幕使用率:" + prams[0].data + "%"
}
}
},
legend: {
data: ['直接访问', '背景'],
show: false
},
grid: {
left: '10%',
right: '10%',
bottom: '10%',
top: '10%',
containLabel: true,
z: 22
},
xAxis: [{
type: 'category',
gridIndex: 0,
data: this.props.xData,
axisTick: {
alignWithLabel: true
},
axisLine: {
lineStyle: {
color: '#0c3b71'
}
},
axisLabel: {
show: true,
color: 'rgb(170,170,170)',
fontSize:16
}
}],
yAxis: [{
type: 'value',
gridIndex: 0,
splitLine: {
show: false
},
axisTick: {
show: false
},
min: this.props.min,
max: 60,
axisLine: {
lineStyle: {
color: '#0c3b71'
}
},
axisLabel: {
color: 'rgb(170,170,170)',
formatter: '{value} %'
}
},
{
type: 'value',
gridIndex: 0,
min: this.props.min,
max: 60,
splitNumber: 12,
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
}
}
}
],
series: [{
name: '屏幕使用率',
type: 'bar',
barWidth: '30%',
xAxisIndex: 0,
yAxisIndex: 0,
itemStyle: {
normal: {
barBorderRadius: 30,
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1, [{
offset: 0,
color: '#00feff'
},
{
offset: 0.5,
color: '#027eff'
},
{
offset: 1,
color: '#0286ff'
}
]
)
}
},
data: this.props.yData,
zlevel: 11
},
{
name: '背景',
type: 'bar',
barWidth: '50%',
xAxisIndex: 0,
yAxisIndex: 1,
barGap: '-135%',
data: [100, 100, 100, 100, 100, 100, 100],
itemStyle: {
normal: {
color: 'rgba(255,255,255,0.1)'
}
},
zlevel: 9
},
]
})
}
render() {
return (
<Div id="Bar2">
</Div>
)
}
}
const Div = styled.div`
width: 100%;
height: 50vh;
border-radius: 1rem;
background-color: #dbe6ff;
`
export default Bar2

+ 167
- 0
web/src/components/echarts/Gannt.jsx Переглянути файл

@ -0,0 +1,167 @@
import React from 'react'
import * as echarts from 'echarts/core';
import {
TitleComponent,
TooltipComponent,
GridComponent,
DataZoomComponent
} from 'echarts/components';
import { CustomChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import styled from 'styled-components'
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DataZoomComponent,
CustomChart,
CanvasRenderer
]);
class Gannt extends React.Component {
constructor(props) {
super(props);
}
renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 0.6;
var rectShape = echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
);
return (
rectShape && {
type: 'rect',
transition: ['shape'],
shape: rectShape,
style: api.style()
}
);
}
componentDidMount() {
// Generate mock data
this.props.categories.forEach( (category, index) => {
var baseTime = this.props.startTime;
for (var i = 0; i < this.props.dataCount; i++) {
var typeItem = this.props.types[Math.round(Math.random() * (this.props.types.length - 1))];
var duration = Math.round(Math.random() * 10000);
this.props.data.push({
name: typeItem.name,
value: [index, baseTime, (baseTime += duration), duration],
itemStyle: {
normal: {
color: typeItem.color
}
}
});
baseTime += Math.round(Math.random() * 2000);
}
});
// echartsidmaindom
var myChart = echarts.init(document.getElementById("Gannt"));
console.log("下面是data");
console.log(this.props.data);
myChart.setOption({
tooltip: {
formatter: function (params) {
// const sec = parseInt(params.value[3], 10); // convert value to number if it's string
// let hours = Math.floor(sec / 3600); // get hours
// let minutes = Math.floor((sec - (hours * 3600)) / 60); // get minutes
// let seconds = sec - (hours * 3600) - (minutes * 60); // get seconds
// // add 0 if value < 10; Example: 2 => 02
// if (hours < 10) {hours = "0"+hours;}
// if (minutes < 10) {minutes = "0"+minutes;}
// if (seconds < 10) {seconds = "0"+seconds;}
// let lastTime = hours+':'+minutes+':'+seconds; // Return is HH : MM : SS
// return params.marker + params.name + ': ' + lastTime;
return "13:52分 \n 13:51分至15:26分(01:35:04) \n 学习"
}
},
dataZoom: [
{
type: 'inside',
filterMode: 'weakFilter',
showDataShadow: false,
top: 400,
labelFormatter: ''
},
{
type: 'inside',
filterMode: 'weakFilter'
}
],
grid: {
height: 'auto',
top: 0
},
xAxis: {
min: this.props.startTime,
max: 86400,
scale: true,
axisLabel: {
formatter: (value) => {
const sec = parseInt(value, 10); // convert value to number if it's string
let hours = Math.floor(sec / 3600); // get hours
let minutes = Math.floor((sec - (hours * 3600)) / 60); // get minutes
let seconds = sec - (hours * 3600) - (minutes * 60); // get seconds
// add 0 if value < 10; Example: 2 => 02
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
return hours+':'+minutes+':'+seconds; // Return is HH : MM : SS
}
}
},
yAxis: {
data: this.props.categories
},
series: [
{
type: 'custom',
renderItem: this.renderItem,
itemStyle: {
opacity: 1
},
encode: {
x: [1, 2],
y: 0
},
data: this.props.data
}
]
});
}
render() {
return (
<Div id="Gannt">
</Div>
)
}
}
export default Gannt
const Div = styled.div`
width: 100%;
height: 45vh;
`

+ 235
- 0
web/src/components/echarts/Pie.jsx Переглянути файл

@ -0,0 +1,235 @@
import React from 'react'
import * as echarts from 'echarts/core';
import {
TitleComponent,
TooltipComponent,
GridComponent,
DataZoomComponent,
LegendComponent
} from 'echarts/components';
import { CustomChart, PieChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import styled from 'styled-components'
import study from '../../assets/study.svg'
import work from '../../assets/work.svg'
import game from '../../assets/game.svg'
import apple from '../../assets/apple.png'
import life from '../../assets/life.svg'
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DataZoomComponent,
CustomChart,
CanvasRenderer,
LegendComponent,
PieChart
]);
class Pie extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
var myChart = echarts.init(document.getElementById("Pie"));
myChart.setOption({
title: {
// text: '',
// subtext: '',
// x: 'center',
// y: 'center',
// textStyle: {
// fontSize:30,
// fontWeight:'normal',
// color: ['#000']
// },
// subtextStyle: {
// color: '#666',
// fontSize: 16
// },
},
grid: {
top: "20%",
// left: 0,
// right: 0,
},
legend: {
show: false,
orient: 'vertical',
top: "middle",
right: "5%",
textStyle: {
color: '#f2f2f2',
fontSize: 25,
},
icon: 'roundRect'
},
series: [
//
{
radius: ['20%', '50%'],
center: ['50%', '50%'],
type: 'pie',
itemStyle: {
normal: {
color: (params) => {
return this.props.colorList[params.dataIndex]
}
}
},
labelLine: {
normal: {
show: true,
length: 15,
length2: 100,
lineStyle: {
color: '#d3d3d3'
},
align: 'right'
},
color: "#000",
emphasis: {
show: true
}
},
label:{
normal:{
formatter: function(params){
var str = '';
switch(params.name){
case '学习':str = '{a|}\n{nameStyle|学习 }'+'{rate|'+params.value+'%}';break;
case '工作':str = '{b|}\n{nameStyle|工作 }'+'{rate|'+params.value+'%}';break;
case '娱乐':str = '{c|}\n{nameStyle|娱乐 }'+'{rate|'+params.value+'%}';break;
case '生活':str = '{d|}\n{nameStyle|生活 }'+'{rate|'+params.value+'%}';break;
}
return str
},
padding: [0, -110],
height: 165,
rich: {
a: {
width:45,
height:45,
lineHeight: 50,
backgroundColor: {
image: study
},
align: 'left'
},
b: {
width:45,
height:45,
lineHeight: 50,
backgroundColor: {
image: work
},
align: 'left'
},
c: {
width:45,
height:45,
lineHeight: 50,
backgroundColor: {
image: game
},
align: 'left'
},
d: {
width:45,
height:45,
lineHeight: 50,
backgroundColor: {
image: life
},
align: 'left'
},
e: {
width:45,
height:45,
lineHeight: 50,
backgroundColor: {
image: apple
},
align: 'left'
},
nameStyle: {
fontSize: 14,
color: "#555",
align: 'left'
},
rate: {
fontSize: 16,
color: "#008000",
align: 'left'
}
}
}
},
data: [
{
value:80,
name:'学习',
},
{value:60, name:'工作'},
{value:10, name:'娱乐'},
{value:20, name:'生活'}],
},
//
{
radius: ['47%', '51%'],
center: ['50%', '50%'],
type: 'pie',
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
labelLine: {
normal: {
show: false
},
emphasis: {
show: false
}
},
animation: true,
tooltip: {
show: false
},
itemStyle: {
normal: {
color:'rgba(250,250,250,0.5)'
}
},
data: [{
value: 1,
}],
}
]
})
}
render() {
return (
<Div id="Pie">
</Div>
)
}
}
const Div = styled.div`
width: 100%;
height: 50vh;
border-radius: 1rem;
background-color: #ebf1ff;
`
export default Pie;

+ 231
- 0
web/src/components/overview/Description.jsx Переглянути файл

@ -0,0 +1,231 @@
import React from 'react'
import styled from 'styled-components'
import { AiFillExperiment } from 'react-icons/ai'
import { AiFillDollarCircle } from 'react-icons/ai'
import { AiOutlineArrowUp } from 'react-icons/ai'
import { AiOutlineArrowDown } from 'react-icons/ai'
import { AiOutlineFieldTime } from 'react-icons/ai'
import { MdOutlineScreenShare, MdOutlineStopScreenShare } from 'react-icons/md'
import Pie from '../echarts/Pie.jsx'
import Bar from '../echarts/Bar.jsx'
import Bar2 from '../echarts/Bar2.jsx'
class Description extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<>
<Section1>
<div className="analytic color1">
<div className="design">
<div className="logo">
<AiOutlineFieldTime></AiOutlineFieldTime>
</div>
<div className="content">
<h3>11h 23m 15s</h3>
</div>
</div>
<div className="total">
<h4>今日屏幕使用时长</h4>
<span className="t1">+10%</span>
<AiOutlineArrowUp className="svg1" />
</div>
</div>
<div className="analytic color2">
<div className="design">
<div className="logo">
<MdOutlineScreenShare />
</div>
<div className="content">
<h3>上午 09:15:34</h3>
</div>
</div>
<div className="total">
<h4>第一次使用</h4>
<span className="t2">-9%</span>
<AiOutlineArrowDown className="svg2" />
</div>
</div>
<div className="analytic color3">
<div className="design">
<div className="logo">
<MdOutlineStopScreenShare />
</div>
<div className="content">
<h3>下午 11:35:20</h3>
</div>
</div>
<div className="total">
<h4>最后一次使用</h4>
<span className="t1">+24%</span>
<AiOutlineArrowUp className="svg1" />
</div>
</div>
</Section1>
<Section2>
<Pie colorList={['#00d488', '#3feed4', '#3bafff', '#f1bb4c', 'rgba(250,250,250,0.5)']}></Pie>
<Bar
colorList={['#f36c6c', '#e6cf4e', '#20d180', '#0093ff']}
datas={[
{
value: 65,
name: 'Chrome'
},
{
value: 18,
name: 'QQ'
},
{
value: 7,
name: 'WeChat'
},
{
value: 3,
name: 'AppTime'
},
{
value: 2,
name: 'Steam'
},
{
value: 2,
name: 'Postman'
},
{
value: 1,
name: 'Navicat'
},
{
value: 1,
name: 'Terminal'
}
]}
maxArr = {(new Array(8)).fill(100)}
></Bar>
</Section2>
<Section2>
<Bar2
data={
[{
"name": "0点",
"value": 0
}, {
"name": "3点",
"value": 0
}, {
"name": "6点",
"value": 0
}, {
"name": "9点",
"value": 0
}, {
"name": "12点",
"value": 0.6
}, {
"name": "15点",
"value": 0.8
}, {
"name": "18点",
"value": 0.95
}]
}
xData={[]}
yData={[]}
min={[]}
></Bar2>
</Section2>
</>
)
}
}
export default Description
const Section1 = styled.section`
margin-top: 2rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4rem;
margin-left: 4rem;
margin-right: 4rem;
.color1 {
background-color: #eef4ff;
}
.color2 {
background-color: #fdf4f5;
}
.color3 {
background-color: #fffce4;
}
.analytic {
padding: 2rem 2rem 2rem 2rem;
border-radius: 1rem;
color: black;
justify-content: space-evenly;
align-items: center;
gap: 1rem;
transition: 0.5s ease-in-out;
&:hover {
background-color: #d4e0ff;
color: black;
svg {
color: black;
}
}
.design {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
.logo {
background-color: white;
border-radius: 1rem;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
padding: 1.5rem;
margin-right: 2rem;
svg {
font-size: 2rem;
}
}
}
.total {
display: flex;
align-items: center;
gap: 1rem;
justify-content: space-evenly;
margin-top: 20px;
.svg1 {
color: green;
}
.svg2 {
color: red;
}
.t1 {
color: green;
}
.t2 {
color: red;
}
h6 {
color: grey;
}
}
}
`
const Section2 = styled.section`
margin-top: 1rem;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
margin-top: 4rem;
margin-left: 4rem;
margin-right: 4rem;
`

+ 28
- 0
web/src/index.css Переглянути файл

@ -0,0 +1,28 @@
* {
margin: 0;
padding: 0;
/* 使边框和内边距不会撑大盒子 */
box-sizing: border-box;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
background-color: #FFFFFF;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
::-webkit-scrollbar {
background-color: #EBECF1;
width: 0.4rw;
}
::-webkit-scrollbar-thumb {
background: black;
}

+ 12
- 0
web/src/index.js Переглянути файл

@ -0,0 +1,12 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

+ 10002
- 0
web/yarn.lock
Різницю між файлами не показано, бо вона завелика
Переглянути файл


Завантаження…
Відмінити
Зберегти