Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop
| | |
| | | "react-router-dom": "^6.26.1", |
| | | "react-syntax-highlighter": "^15.5.0", |
| | | "react-to-print": "^2.14.11", |
| | | "recharts": "^2.15.0", |
| | | "svgpath": "^2.6.0", |
| | | "three": "^0.155.0", |
| | | "tweedle.js": "^2.1.0" |
| | |
| | | "integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-array": { |
| | | "version": "3.2.1", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", |
| | | "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-color": { |
| | | "version": "3.1.3", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", |
| | | "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-ease": { |
| | | "version": "3.0.2", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", |
| | | "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-interpolate": { |
| | | "version": "3.0.4", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", |
| | | "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@types/d3-color": "*" |
| | | } |
| | | }, |
| | | "node_modules/@types/d3-path": { |
| | | "version": "3.1.1", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", |
| | | "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-scale": { |
| | | "version": "4.0.9", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", |
| | | "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@types/d3-time": "*" |
| | | } |
| | | }, |
| | | "node_modules/@types/d3-shape": { |
| | | "version": "3.1.7", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", |
| | | "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@types/d3-path": "*" |
| | | } |
| | | }, |
| | | "node_modules/@types/d3-time": { |
| | | "version": "3.0.4", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", |
| | | "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/d3-timer": { |
| | | "version": "3.0.2", |
| | | "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", |
| | | "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@types/earcut": { |
| | | "version": "2.1.4", |
| | | "resolved": "https://registry.npmmirror.com/@types/earcut/-/earcut-2.1.4.tgz", |
| | |
| | | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/d3-array": { |
| | | "version": "3.2.4", |
| | | "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", |
| | | "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "internmap": "1 - 2" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-color": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", |
| | | "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", |
| | | "license": "ISC", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-ease": { |
| | | "version": "3.0.1", |
| | | "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", |
| | | "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", |
| | | "license": "BSD-3-Clause", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-format": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", |
| | | "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", |
| | | "license": "ISC", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-interpolate": { |
| | | "version": "3.0.1", |
| | | "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", |
| | | "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "d3-color": "1 - 3" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-path": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", |
| | | "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", |
| | | "license": "ISC", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-scale": { |
| | | "version": "4.0.2", |
| | | "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", |
| | | "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "d3-array": "2.10.0 - 3", |
| | | "d3-format": "1 - 3", |
| | | "d3-interpolate": "1.2.0 - 3", |
| | | "d3-time": "2.1.1 - 3", |
| | | "d3-time-format": "2 - 4" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-shape": { |
| | | "version": "3.2.0", |
| | | "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", |
| | | "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "d3-path": "^3.1.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-time": { |
| | | "version": "3.1.0", |
| | | "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", |
| | | "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "d3-array": "2 - 3" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-time-format": { |
| | | "version": "4.1.0", |
| | | "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", |
| | | "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", |
| | | "license": "ISC", |
| | | "dependencies": { |
| | | "d3-time": "1 - 3" |
| | | }, |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/d3-timer": { |
| | | "version": "3.0.1", |
| | | "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", |
| | | "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", |
| | | "license": "ISC", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/data-view-buffer": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz", |
| | |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/decimal.js-light": { |
| | | "version": "2.5.1", |
| | | "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", |
| | | "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/decode-uri-component": { |
| | | "version": "0.2.2", |
| | |
| | | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", |
| | | "dev": true, |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/fast-equals": { |
| | | "version": "5.2.2", |
| | | "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", |
| | | "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=6.0.0" |
| | | } |
| | | }, |
| | | "node_modules/fast-glob": { |
| | | "version": "3.3.3", |
| | |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/internmap": { |
| | | "version": "2.0.3", |
| | | "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", |
| | | "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", |
| | | "license": "ISC", |
| | | "engines": { |
| | | "node": ">=12" |
| | | } |
| | | }, |
| | | "node_modules/is-alphabetical": { |
| | |
| | | "react-dom": ">=16.8" |
| | | } |
| | | }, |
| | | "node_modules/react-smooth": { |
| | | "version": "4.0.4", |
| | | "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", |
| | | "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "fast-equals": "^5.0.1", |
| | | "prop-types": "^15.8.1", |
| | | "react-transition-group": "^4.4.5" |
| | | }, |
| | | "peerDependencies": { |
| | | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", |
| | | "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" |
| | | } |
| | | }, |
| | | "node_modules/react-syntax-highlighter": { |
| | | "version": "15.6.1", |
| | | "resolved": "https://registry.npmmirror.com/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", |
| | |
| | | "react": ">=16.6.0", |
| | | "react-dom": ">=16.6.0" |
| | | } |
| | | }, |
| | | "node_modules/recharts": { |
| | | "version": "2.15.4", |
| | | "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", |
| | | "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "clsx": "^2.0.0", |
| | | "eventemitter3": "^4.0.1", |
| | | "lodash": "^4.17.21", |
| | | "react-is": "^18.3.1", |
| | | "react-smooth": "^4.0.4", |
| | | "recharts-scale": "^0.4.4", |
| | | "tiny-invariant": "^1.3.1", |
| | | "victory-vendor": "^36.6.8" |
| | | }, |
| | | "engines": { |
| | | "node": ">=14" |
| | | }, |
| | | "peerDependencies": { |
| | | "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", |
| | | "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" |
| | | } |
| | | }, |
| | | "node_modules/recharts-scale": { |
| | | "version": "0.4.5", |
| | | "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", |
| | | "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "decimal.js-light": "^2.4.1" |
| | | } |
| | | }, |
| | | "node_modules/recharts/node_modules/react-is": { |
| | | "version": "18.3.1", |
| | | "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", |
| | | "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/redux": { |
| | | "version": "4.2.1", |
| | |
| | | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" |
| | | } |
| | | }, |
| | | "node_modules/victory-vendor": { |
| | | "version": "36.9.2", |
| | | "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", |
| | | "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", |
| | | "license": "MIT AND ISC", |
| | | "dependencies": { |
| | | "@types/d3-array": "^3.0.3", |
| | | "@types/d3-ease": "^3.0.0", |
| | | "@types/d3-interpolate": "^3.0.1", |
| | | "@types/d3-scale": "^4.0.2", |
| | | "@types/d3-shape": "^3.1.0", |
| | | "@types/d3-time": "^3.0.0", |
| | | "@types/d3-timer": "^3.0.0", |
| | | "d3-array": "^3.1.6", |
| | | "d3-ease": "^3.0.1", |
| | | "d3-interpolate": "^3.0.1", |
| | | "d3-scale": "^4.0.2", |
| | | "d3-shape": "^3.1.0", |
| | | "d3-time": "^3.0.0", |
| | | "d3-timer": "^3.0.1" |
| | | } |
| | | }, |
| | | "node_modules/vite": { |
| | | "version": "5.4.19", |
| | | "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.19.tgz", |
| | |
| | | "react-to-print": "^2.14.11", |
| | | "svgpath": "^2.6.0", |
| | | "three": "^0.155.0", |
| | | "tweedle.js": "^2.1.0" |
| | | "tweedle.js": "^2.1.0", |
| | | "recharts": "^2.15.0" |
| | | }, |
| | | "devDependencies": { |
| | | "@types/node": "^20.10.7", |
| | |
| | | "vite": "^5.3.5" |
| | | }, |
| | | "name": "rsf" |
| | | } |
| | | } |
| | |
| | | } |
| | | }, |
| | | page: { |
| | | dashboard: { |
| | | welcome: { |
| | | title: 'Welcome to the WMS website', |
| | | }, |
| | | }, |
| | | welcome: { |
| | | index: ' Welcome to the RSF Management System.', |
| | | tech: ' Technology stack: Java 17, SpringBoot2.5.3, Mybatis-plus_3.4.1, Spring Security, Druid 1.2.6, Redis, Mysql5.7, Node18, ReactJs, Material UI5.16, Axios, React-Admin5.1' |
| | |
| | | locDeadReport: '库存停滞报表', |
| | | stockStatistic: '日入库汇总查询', |
| | | outStatistic: '日出库汇总查询', |
| | | inStatistic: '日入库汇总查询', |
| | | inStatistic: '日入库汇总查询', |
| | | inStatisticItem: '日入库明细查询', |
| | | outStatisticItem: '日出库明细查询', |
| | | statisticCount: '日出入库汇总统计', |
| | |
| | | } |
| | | }, |
| | | page: { |
| | | dashboard: { |
| | | welcome: { |
| | | title: '欢迎使用 WMS 系统', |
| | | }, |
| | | }, |
| | | welcome: { |
| | | index: ' 欢迎使用RSF管理系统', |
| | | tech: ' 技术栈: Java17, SpringBoot2.5.3, Mybatis-plus_3.4.1, Spring Security, Druid 1.2.6, Redis, Mysql5.7, Node18, ReactJs, Material UI5.16, Axios, React-Admin5.1' |
New file |
| | |
| | | import * as React from 'react'; |
| | | import { FC, createElement } from 'react'; |
| | | import { Card, Box, Typography, Divider } from '@mui/material'; |
| | | import { Link } from 'react-router-dom'; |
| | | |
| | | const CardWithIcon = ({ icon, title, subtitle, to, children }) => ( |
| | | <Card |
| | | sx={{ |
| | | minHeight: 52, |
| | | display: 'flex', |
| | | flexDirection: 'column', |
| | | flex: '1', |
| | | '& a': { |
| | | textDecoration: 'none', |
| | | color: 'inherit', |
| | | }, |
| | | }} |
| | | > |
| | | <Box |
| | | sx={{ |
| | | position: 'relative', |
| | | overflow: 'hidden', |
| | | padding: '16px', |
| | | display: 'flex', |
| | | justifyContent: 'space-between', |
| | | alignItems: 'center', |
| | | '& .icon': { |
| | | color: 'primary.main', |
| | | }, |
| | | '&:before': { |
| | | position: 'absolute', |
| | | top: '50%', |
| | | left: 0, |
| | | display: 'block', |
| | | content: `''`, |
| | | height: '200%', |
| | | aspectRatio: '1', |
| | | transform: 'translate(-30%, -60%)', |
| | | borderRadius: '50%', |
| | | backgroundColor: 'primary.main', |
| | | opacity: 0.15, |
| | | }, |
| | | }} |
| | | > |
| | | <Box width="3em" className="icon"> |
| | | {createElement(icon, { fontSize: 'large' })} |
| | | </Box> |
| | | <Box textAlign="right"> |
| | | <Typography color="textSecondary">{title}</Typography> |
| | | <Typography variant="h5" component="h2"> |
| | | {subtitle || ' '} |
| | | </Typography> |
| | | </Box> |
| | | </Box> |
| | | {children && <Divider />} |
| | | {children} |
| | | </Card> |
| | | ); |
| | | |
| | | export default CardWithIcon; |
New file |
| | |
| | | import * as React from 'react'; |
| | | import { |
| | | Avatar, |
| | | Box, |
| | | Button, |
| | | List, |
| | | ListItem, |
| | | ListItemAvatar, |
| | | ListItemButton, |
| | | ListItemText, |
| | | } from '@mui/material'; |
| | | import CommentIcon from '@mui/icons-material/Comment'; |
| | | import { Link } from 'react-router-dom'; |
| | | import { |
| | | ReferenceField, |
| | | FunctionField, |
| | | useGetList, |
| | | useTranslate, |
| | | useIsDataLoaded, |
| | | } from 'react-admin'; |
| | | import CardWithIcon from '../components/CardWithIcon'; |
| | | |
| | | const NbCard = (props) => { |
| | | const { list, ...rest } = props; |
| | | const translate = useTranslate(); |
| | | const { |
| | | data: reviews, |
| | | total, |
| | | isPending, |
| | | } = useGetList('reviews', { |
| | | filter: { status: 'pending' }, |
| | | sort: { field: 'date', order: 'DESC' }, |
| | | pagination: { page: 1, perPage: 100 }, |
| | | }); |
| | | |
| | | const display = 'display'; |
| | | const newList = list.concat(list); |
| | | |
| | | return ( |
| | | <CardWithIcon |
| | | icon={CommentIcon} |
| | | title={translate('pos.dashboard.pending_reviews')} |
| | | subtitle={total} |
| | | {...rest} |
| | | > |
| | | <List sx={{ display }}> |
| | | {newList?.map((record) => ( |
| | | <ListItem key={record.id} disablePadding> |
| | | <ListItemButton |
| | | alignItems="flex-start" |
| | | component={Link} |
| | | to={`/task/${record.id}`} |
| | | > |
| | | {/* <ListItemAvatar> |
| | | <Avatar |
| | | sx={{ |
| | | // bgcolor: 'primary.main', |
| | | bgcolor: '#a2beeaff', |
| | | color: 'primary.contrastText', // 避免白字白底 |
| | | // width: 40, |
| | | // height: 40, |
| | | // fontSize: 16, |
| | | }} |
| | | > |
| | | {record.id} |
| | | </Avatar> |
| | | </ListItemAvatar> */} |
| | | |
| | | <ListItemText |
| | | // primary={ |
| | | // <StarRatingField |
| | | // record={record} |
| | | // source="rating" |
| | | // /> |
| | | // } |
| | | primary={record.date + record.date} |
| | | secondary={record.total} |
| | | sx={{ |
| | | overflowY: 'hidden', |
| | | height: '3em', |
| | | display: '-webkit-box', |
| | | WebkitLineClamp: 2, |
| | | WebkitBoxOrient: 'vertical', |
| | | paddingRight: 0, |
| | | }} |
| | | /> |
| | | </ListItemButton> |
| | | </ListItem> |
| | | ))} |
| | | </List> |
| | | <Box flexGrow={1}> </Box> |
| | | <Button |
| | | sx={{ borderRadius: 0 }} |
| | | component={Link} |
| | | to="/task" |
| | | size="small" |
| | | color="primary" |
| | | > |
| | | <Box p={1} sx={{ color: 'primary.main' }}> |
| | | {translate('pos.dashboard.all_reviews')} |
| | | </Box> |
| | | </Button> |
| | | </CardWithIcon> |
| | | ); |
| | | }; |
| | | |
| | | export default NbCard; |
New file |
| | |
| | | import * as React from 'react'; |
| | | import { Card, CardHeader, CardContent } from '@mui/material'; |
| | | import { |
| | | ResponsiveContainer, |
| | | AreaChart, |
| | | Area, |
| | | XAxis, |
| | | YAxis, |
| | | CartesianGrid, |
| | | Tooltip, |
| | | } from 'recharts'; |
| | | import { useTranslate } from 'react-admin'; |
| | | import { format, subDays, addDays } from 'date-fns'; |
| | | |
| | | const lastDay = new Date(); |
| | | const lastMonthDays = Array.from({ length: 30 }, (_, i) => subDays(lastDay, i)); |
| | | const aMonthAgo = subDays(new Date(), 30); |
| | | |
| | | const dateFormatter = (date) => |
| | | new Date(date).toLocaleDateString(); |
| | | |
| | | const aggregateOrdersByDay = (orders) => |
| | | orders |
| | | .filter((order) => order.status !== 'cancelled') |
| | | .reduce( |
| | | (acc, curr) => { |
| | | const day = format(curr.date, 'yyyy-MM-dd'); |
| | | if (!acc[day]) { |
| | | acc[day] = 0; |
| | | } |
| | | acc[day] += curr.total; |
| | | return acc; |
| | | }, |
| | | {} |
| | | ); |
| | | |
| | | const getRevenuePerDay = (orders) => { |
| | | const daysWithRevenue = aggregateOrdersByDay(orders); |
| | | return lastMonthDays.map(date => ({ |
| | | date: date.getTime(), |
| | | total: daysWithRevenue[format(date, 'yyyy-MM-dd')] || 0, |
| | | })); |
| | | }; |
| | | |
| | | const NbChart = (props) => { |
| | | const { orders } = props; |
| | | const translate = useTranslate(); |
| | | if (!orders) return null; |
| | | |
| | | return ( |
| | | <Card> |
| | | <CardHeader title={translate('pos.dashboard.month_history')} /> |
| | | <CardContent> |
| | | <div style={{ width: '100%', height: 300 }}> |
| | | <ResponsiveContainer> |
| | | <AreaChart data={getRevenuePerDay(orders)}> |
| | | <defs> |
| | | <linearGradient |
| | | id="colorUv" |
| | | x1="0" |
| | | y1="0" |
| | | x2="0" |
| | | y2="1" |
| | | > |
| | | <stop |
| | | offset="5%" |
| | | stopColor="#5091abff" |
| | | stopOpacity={0.8} |
| | | /> |
| | | <stop |
| | | offset="95%" |
| | | stopColor="#5091abff" |
| | | stopOpacity={0} |
| | | /> |
| | | </linearGradient> |
| | | </defs> |
| | | <XAxis |
| | | dataKey="date" |
| | | name="Date" |
| | | type="number" |
| | | scale="time" |
| | | domain={[ |
| | | addDays(aMonthAgo, 1).getTime(), |
| | | new Date().getTime(), |
| | | ]} |
| | | tickFormatter={dateFormatter} |
| | | /> |
| | | <YAxis dataKey="total" name="Revenue" unit="€" /> |
| | | <CartesianGrid strokeDasharray="3 3" /> |
| | | <Tooltip |
| | | cursor={{ strokeDasharray: '3 3' }} |
| | | formatter={(value) => |
| | | new Intl.NumberFormat(undefined, { |
| | | style: 'currency', |
| | | currency: 'USD', |
| | | }).format(value) |
| | | } |
| | | labelFormatter={(label) => |
| | | dateFormatter(label) |
| | | } |
| | | /> |
| | | <Area |
| | | type="monotone" |
| | | dataKey="total" |
| | | stroke="#5091abff" |
| | | strokeWidth={2} |
| | | fill="url(#colorUv)" |
| | | /> |
| | | </AreaChart> |
| | | </ResponsiveContainer> |
| | | </div> |
| | | </CardContent> |
| | | </Card> |
| | | ); |
| | | }; |
| | | |
| | | export default NbChart; |
New file |
| | |
| | | import * as React from 'react'; |
| | | import { useTranslate, useReference } from 'react-admin'; |
| | | import { |
| | | ListItem, |
| | | ListItemSecondaryAction, |
| | | ListItemAvatar, |
| | | ListItemText, |
| | | Avatar, |
| | | Box, |
| | | ListItemButton, |
| | | Card, |
| | | CardHeader, |
| | | List, |
| | | } from '@mui/material'; |
| | | import { Link } from 'react-router-dom'; |
| | | |
| | | const NbList = (props) => { |
| | | const { orders = [] } = props; |
| | | const translate = useTranslate(); |
| | | |
| | | return ( |
| | | <Card sx={{ flex: 1 }}> |
| | | <CardHeader title={translate('pos.dashboard.pending_orders')} /> |
| | | <List dense={true}> |
| | | {orders.map(record => ( |
| | | <PendingOrder key={record.id} order={record} /> |
| | | ))} |
| | | </List> |
| | | </Card> |
| | | ); |
| | | }; |
| | | |
| | | export const PendingOrder = (props) => { |
| | | const { order } = props; |
| | | console.log(order); |
| | | |
| | | const translate = useTranslate(); |
| | | const { referenceRecord: customer, isPending } = useReference({ |
| | | reference: 'customers', |
| | | id: order.customer_id, |
| | | }); |
| | | |
| | | return ( |
| | | <ListItem disablePadding> |
| | | <ListItemButton component={Link} to={`/orders/${order.id}`}> |
| | | {/* <ListItemAvatar> |
| | | {isPending ? ( |
| | | <Avatar /> |
| | | ) : ( |
| | | <Avatar |
| | | src={`${customer?.avatar}?size=32x32`} |
| | | sx={{ bgcolor: 'background.paper' }} |
| | | alt={`${customer?.first_name} ${customer?.last_name}`} |
| | | /> |
| | | )} |
| | | </ListItemAvatar> */} |
| | | <ListItemText |
| | | primary={new Date(order.date).toLocaleString('en-GB')} |
| | | secondary={translate('pos.dashboard.order.items', { |
| | | name: order.name |
| | | })} |
| | | /> |
| | | <ListItemSecondaryAction> |
| | | <Box |
| | | component="span" |
| | | sx={{ |
| | | marginRight: '1em', |
| | | color: 'text.primary', |
| | | }} |
| | | > |
| | | {order.total}$ |
| | | </Box> |
| | | </ListItemSecondaryAction> |
| | | </ListItemButton> |
| | | </ListItem> |
| | | ); |
| | | }; |
| | | |
| | | export default NbList; |
New file |
| | |
| | | import * as React from 'react'; |
| | | import { Box, Card, CardActions, Button, Typography, useTheme } from '@mui/material'; |
| | | import { useNavigate } from 'react-router-dom'; |
| | | import { useTranslate } from 'react-admin'; |
| | | import AssignmentIcon from '@mui/icons-material/Assignment'; |
| | | import AccountCircleIcon from '@mui/icons-material/AccountCircle'; |
| | | |
| | | import publishArticleImage from './welcome_illustration.svg'; |
| | | |
| | | const Welcome = () => { |
| | | const translate = useTranslate(); |
| | | const navigate = useNavigate(); |
| | | const theme = useTheme(); |
| | | const isLight = theme.palette.mode === 'light'; |
| | | |
| | | return ( |
| | | <Card |
| | | sx={{ |
| | | background: theme => |
| | | `linear-gradient(45deg, |
| | | ${isLight ? theme.palette.secondary.dark : theme.palette.primary.dark} 0%, |
| | | ${isLight ? theme.palette.secondary.light : theme.palette.primary.light} 50%, |
| | | ${theme.palette.primary.dark} 100%)`, |
| | | color: theme => theme.palette.primary.contrastText, |
| | | padding: '20px', |
| | | // paddingBottom: '50px', |
| | | marginTop: 2, |
| | | marginBottom: '1em', |
| | | width: '100%', |
| | | overflow: 'visible' |
| | | }} |
| | | > |
| | | <Box display="flex"> |
| | | <Box flex="1"> |
| | | <Typography variant="h5" component="h2" gutterBottom> |
| | | {translate('page.dashboard.welcome.title')} |
| | | </Typography> |
| | | <Box maxWidth="40em"> |
| | | <Typography variant="body1" component="p" gutterBottom> |
| | | {translate('page.dashboard.welcome.title')} |
| | | </Typography> |
| | | </Box> |
| | | <CardActions |
| | | sx={{ |
| | | padding: { xs: 0, xl: null }, |
| | | flexWrap: { xs: 'wrap', xl: null }, |
| | | '& a': { |
| | | marginTop: { xs: '1em', xl: null }, |
| | | marginLeft: { xs: '0!important', xl: null }, |
| | | marginRight: { xs: '1em', xl: null }, |
| | | }, |
| | | marginTop: 3, |
| | | }} |
| | | > |
| | | <Button |
| | | variant="contained" |
| | | startIcon={<AssignmentIcon />} |
| | | onClick={() => { |
| | | navigate('/task') |
| | | }} |
| | | > |
| | | {translate('menu.task')} |
| | | </Button> |
| | | <Button |
| | | variant="contained" |
| | | startIcon={<AccountCircleIcon />} |
| | | onClick={() => { |
| | | navigate('/warehouseStock') |
| | | }} |
| | | > |
| | | {translate('menu.warehouseStock')} |
| | | </Button> |
| | | </CardActions> |
| | | </Box> |
| | | <Box |
| | | display={{ xs: 'none', sm: 'none', md: 'block' }} |
| | | sx={{ |
| | | background: `url(${publishArticleImage}) top right / cover`, |
| | | marginLeft: 'auto', |
| | | }} |
| | | width="16em" |
| | | height="9em" |
| | | overflow="hidden" |
| | | /> |
| | | </Box> |
| | | </Card> |
| | | ); |
| | | }; |
| | | |
| | | export default Welcome; |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { useNavigate } from 'react-router-dom'; |
| | | import { useTheme } from '@mui/material/styles'; |
| | | import { useTranslate, useAuthProvider } from 'react-admin'; |
| | | import { useTranslate, useAuthProvider, Title, useNotify } from 'react-admin'; |
| | | import { WordEffect } from './WordEffect'; |
| | | import { getSystemDicts } from '@/api/auth' |
| | | import Welcome from "./Welcome"; |
| | | import CardWithIcon from '../components/CardWithIcon'; |
| | | import SensorOccupiedIcon from '@mui/icons-material/SensorOccupied'; |
| | | import WifiIcon from '@mui/icons-material/Wifi'; |
| | | import request from '@/utils/request'; |
| | | import { Box, Typography, LinearProgress, Stack } from '@mui/material'; |
| | | import NbChart from "./NbChart"; |
| | | import NbList from "./NbList"; |
| | | import NbCard from "./NbCard"; |
| | | |
| | | const styles = { |
| | | flex: { display: 'flex' }, |
| | | flexColumn: { display: 'flex', flexDirection: 'column' }, |
| | | leftCol: { flex: 1, marginRight: '0.5em' }, |
| | | rightCol: { flex: 1, marginLeft: '0.5em' }, |
| | | singleCol: { marginTop: '1em', marginBottom: '1em' }, |
| | | }; |
| | | |
| | | const Dashboard = () => { |
| | | const authProvider = useAuthProvider(); |
| | |
| | | |
| | | return ( |
| | | <> |
| | | <Title title={"menu.dashboard"} /> |
| | | <Welcome /> |
| | | <DashboardSummaryView /> |
| | | <div |
| | | style={{ |
| | | boxSizing: 'border-box', |
| | |
| | | padding: '2rem 1rem', |
| | | }} |
| | | > |
| | | <WordEffect |
| | | {/* <WordEffect |
| | | words={translate('page.welcome.index')} |
| | | color={theme.palette.mode === 'light' ? '#666' : '#eeeeee'} |
| | | /> |
| | | <WordEffect |
| | | words={translate('page.welcome.tech')} |
| | | color={theme.palette.mode === 'light' ? '#666' : '#eeeeee'} |
| | | /> |
| | | /> */} |
| | | </div> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | const DashboardSummaryView = () => { |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const [statistic, setStatistic] = useState(null); |
| | | |
| | | useEffect(() => { |
| | | request.get('/dashboard/member/statistic', { |
| | | params: {} |
| | | }).then(res => { |
| | | const { code, msg, data } = res.data; |
| | | if (code === 200) { |
| | | setStatistic(data); |
| | | } else { |
| | | // notify(msg, { type: 'error', messageArgs: { _: msg } }); |
| | | } |
| | | }).catch((error) => { |
| | | // notify(error.message, { type: 'error', messageArgs: { _: error.message } }); |
| | | console.error(error); |
| | | }) |
| | | }, []) |
| | | |
| | | const recentOrders = [ |
| | | { |
| | | id: 1, |
| | | name: 'a', |
| | | date: "2025-08-10T12:23:56.959Z", |
| | | total: 138.94 |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: 'b', |
| | | date: "2025-08-03T07:45:00.304Z", |
| | | total: 214.66 |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: 'c', |
| | | date: "2025-07-28T00:20:10.968Z", |
| | | total: 68.19 |
| | | }, |
| | | { |
| | | id: 4, |
| | | name: 'd', |
| | | date: "2025-07-22T20:39:00.293Z", |
| | | total: 36.56 |
| | | }, |
| | | { |
| | | id: 5, |
| | | name: 'e', |
| | | date: "2025-07-16T17:40:24.791Z", |
| | | total: 100.82 |
| | | }, |
| | | ] |
| | | |
| | | return ( |
| | | <> |
| | | <div style={styles.flex}> |
| | | <div style={styles.leftCol}> |
| | | <div style={styles.flex}> |
| | | <CardWithIcon |
| | | icon={WifiIcon} |
| | | title={translate('page.member.header.onlineMembers')} |
| | | subtitle={`${statistic?.membersOnlineQua}`} |
| | | /> |
| | | <Spacer /> |
| | | <CardWithIcon |
| | | icon={SensorOccupiedIcon} |
| | | title={translate('page.member.header.totalMembers')} |
| | | subtitle={`${statistic?.membersTotalQua}`} |
| | | /> |
| | | </div> |
| | | <div style={styles.singleCol}> |
| | | <NbChart orders={recentOrders} /> |
| | | </div> |
| | | <div style={styles.singleCol}> |
| | | <NbList orders={recentOrders} /> |
| | | </div> |
| | | </div> |
| | | <div style={styles.rightCol}> |
| | | <div style={styles.flex}> |
| | | <NbCard |
| | | icon={WifiIcon} |
| | | title={translate('page.member.header.onlineMembers')} |
| | | subtitle={`${statistic?.membersOnlineQua}`} |
| | | to={{ |
| | | pathname: '/task', |
| | | search: JSON.stringify({ |
| | | filter: JSON.stringify({ status: 1 }), |
| | | }), |
| | | }} |
| | | list={recentOrders} |
| | | /> |
| | | <Spacer /> |
| | | <NbCard |
| | | icon={SensorOccupiedIcon} |
| | | title={translate('page.member.header.totalMembers')} |
| | | subtitle={`${statistic?.membersTotalQua}`} |
| | | to={{ |
| | | pathname: '/task', |
| | | search: JSON.stringify({ |
| | | filter: JSON.stringify({ status: 1 }), |
| | | }), |
| | | }} |
| | | list={recentOrders} |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | {/* <Box sx={{ |
| | | display: 'flex', |
| | | mt: 2, |
| | | gap: 2, |
| | | justifyContent: 'space-between', |
| | | }}> |
| | | <CardWithIcon |
| | | icon={WifiIcon} |
| | | title={translate('page.member.header.onlineMembers')} |
| | | subtitle={`${statistic?.membersOnlineQua}`} |
| | | /> |
| | | <CardWithIcon |
| | | icon={SensorOccupiedIcon} |
| | | title={translate('page.member.header.totalMembers')} |
| | | subtitle={`${statistic?.membersTotalQua}`} |
| | | /> |
| | | <CardWithIcon |
| | | icon={WifiIcon} |
| | | title={translate('page.member.header.onlineMembers')} |
| | | subtitle={`${statistic?.membersOnlineQua}`} |
| | | /> |
| | | <CardWithIcon |
| | | icon={SensorOccupiedIcon} |
| | | title={translate('page.member.header.totalMembers')} |
| | | subtitle={`${statistic?.membersTotalQua}`} |
| | | /> |
| | | </Box > */} |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | const Spacer = () => <span style={{ width: '1em' }} />; |
| | | |
| | | export default Dashboard; |
New file |
| | |
| | | <svg id="b66c9c51-8109-402d-a3f9-100a5bb3d153" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="890.30174" height="489.29978" viewBox="0 0 890.30174 489.29978"><title>work_together</title><rect x="182.97245" y="0.39886" width="703.57565" height="450.60114" fill="#e6e6e6"/><rect x="245.18701" y="60.90722" width="254" height="261" fill="#fff"/><rect x="594.18701" y="65.96874" width="254" height="317" fill="#fff"/><ellipse cx="844.80174" cy="477.2616" rx="45.5" ry="6.5" fill="#e6e6e6"/><ellipse cx="389.89961" cy="477.40722" rx="45.5" ry="6.5" fill="#e6e6e6"/><ellipse cx="104.42498" cy="470.90722" rx="104.42498" ry="5" fill="#e6e6e6"/><rect x="182.67203" width="703.57565" height="29.89047" fill="#567aae"/><circle cx="204.88423" cy="15.28159" r="5.53997" fill="#e6e6e6"/><circle cx="225.91256" cy="15.28159" r="5.53997" fill="#e6e6e6"/><circle cx="246.94089" cy="15.28159" r="5.53997" fill="#e6e6e6"/><path d="M947.03614,356.34879H945.4975V314.19823a24.3956,24.3956,0,0,0-24.39567-24.39563H831.80022a24.3956,24.3956,0,0,0-24.39567,24.39563V545.43948a24.3956,24.3956,0,0,0,24.39567,24.39563h89.30161a24.3956,24.3956,0,0,0,24.39567-24.39563V386.35227h1.53864Z" transform="translate(-154.84913 -205.35011)" fill="#3f3d56"/><path d="M921.08621,296.1495H909.42939a8.6555,8.6555,0,0,1-8.01381,11.92446H850.25579A8.65552,8.65552,0,0,1,842.242,296.1495H831.35448a18.21836,18.21836,0,0,0-18.21838,18.21834v230.902a18.21836,18.21836,0,0,0,18.21838,18.21836h89.73173a18.21837,18.21837,0,0,0,18.21839-18.21836v-230.902A18.21837,18.21837,0,0,0,921.08621,296.1495Z" transform="translate(-154.84913 -205.35011)" fill="#fff"/><rect x="284.09023" y="225.77561" width="176.5444" height="8.05267" fill="#e6e6e6"/><rect x="284.09023" y="251.77561" width="176.5444" height="8.05267" fill="#567aae"/><rect x="284.09023" y="277.77561" width="176.5444" height="8.05267" fill="#e6e6e6"/><rect x="670.83934" y="243.34556" width="103.06376" height="8.05267" fill="#e6e6e6"/><rect x="670.83934" y="268.34556" width="103.06376" height="8.05267" fill="#e6e6e6"/><rect x="670.83934" y="293.34556" width="103.06376" height="8.05267" fill="#e6e6e6"/><rect x="922.35071" y="606.56341" width="17.17729" height="17.17729" transform="translate(1391.24229 -521.13741) rotate(90)" fill="#3f3d56"/><rect x="894.67619" y="606.56341" width="17.17729" height="17.17729" transform="translate(1363.56776 -493.46289) rotate(90)" fill="#567aae"/><rect x="867.00166" y="606.56341" width="17.17729" height="17.17729" transform="translate(1335.89323 -465.78836) rotate(90)" fill="#3f3d56"/><rect x="839.32713" y="606.56341" width="17.17729" height="17.17729" transform="translate(1308.2187 -438.11383) rotate(90)" fill="#3f3d56"/><rect x="811.6526" y="606.56341" width="17.17729" height="17.17729" transform="translate(1280.54418 -410.4393) rotate(90)" fill="#3f3d56"/><rect x="692.7424" y="138.9903" width="57.25764" height="57.25764" fill="#567aae"/><path d="M504.45442,480.943l-.74114,1.48227-2.2234-11.117s-2.96454-11.85815,2.96454-11.85815,4.4468,11.85815,4.4468,11.85815v8.15248Z" transform="translate(-154.84913 -205.35011)" fill="#a0616a"/><path d="M601.69555,479.42524l.74113,1.48227,2.22341-11.117s2.96454-11.85815-2.96454-11.85815-4.44681,11.85815-4.44681,11.85815V477.943Z" transform="translate(-154.84913 -205.35011)" fill="#a0616a"/><polygon points="382.215 358.94 373.322 413.784 377.768 467.145 388.144 462.699 386.662 422.677 397.038 390.808 399.261 428.606 394.815 467.886 408.155 469.369 417.79 388.585 417.049 361.163 382.215 358.94" fill="#2f2e41"/><path d="M537.06434,665.82526l-5.18794,8.15248V692.194a2.209,2.209,0,0,0,1.85635,2.18045c2.5428.41721,6.97037.71364,8.51954-1.86831,2.2234-3.70567.74113-11.85816.74113-11.85816s2.96454-5.92907,1.48227-10.37588-2.96454-5.18794-2.96454-5.18794Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M559.29839,673.23661l1.48227,2.2234s2.2234,2.22341.74113,3.70568a28.96565,28.96565,0,0,0-2.96454,3.70567s-8.15248,2.2234-8.15248-.74114v-9.63475Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><circle cx="401.77827" cy="288.79506" r="9.82427" fill="#a0616a"/><polygon points="395.185 291.867 394.444 305.949 407.784 306.69 407.043 292.608 395.185 291.867" fill="#a0616a"/><path d="M564.48633,512.41037l-2.10384-5.13957s-9.75432-3.75405-12.71885-.04838l-1.48227,4.44681-11.85816-2.96454-6.67021,14.8227,5.92908,42.24468s15.56382,20.01064,36.3156.74113l5.92908-40.02127L573.38,510.9281Z" transform="translate(-154.84913 -205.35011)" fill="#575a89"/><polygon points="417.049 308.543 418.531 305.578 433.354 296.684 442.4 269.907 449.4 272.907 441.506 304.837 420.013 324.847 417.049 308.543" fill="#575a89"/><polygon points="382.956 304.837 381.474 303.355 365.91 293.72 354.793 271.486 345.9 274.45 355.534 301.872 379.251 321.142 382.956 304.837" fill="#575a89"/><path d="M563.91892,479.10047l1.60629-.80315-2.40943-.80314V476.691s-12.04715-4.81886-13.65343,3.21257a16.14329,16.14329,0,0,0,0,19.27544v2.40942l12.85029,1.60629,1.60628-4.81886S571.95036,483.91933,563.91892,479.10047Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M269.93891,565.15978l-2.85542,1.42771s-11.42168,5.23493-8.09036,8.09035,12.37349-2.85542,12.37349-2.85542l1.90361-2.37952Z" transform="translate(-154.84913 -205.35011)" fill="#ffb8b8"/><polygon points="198.633 359.099 189.807 418.346 176.481 459.749 169.343 456.418 176.005 399.786 156.969 383.605 158.397 359.81 198.633 359.099" fill="#2f2e41"/><path d="M323.24006,663.19583s8.09036-4.28313,8.56626,1.90361l-.95181,6.18674s2.85542,10.94578-6.66264,8.56626-2.85542-9.51806-2.85542-9.51806Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M318.00513,583.72l-6.18674,5.23493s0,32.36142,4.28312,37.12045,31.40961,29.0301,32.36142,29.9819,5.23494-9.51806,5.23494-9.51806l-25.69878-29.9819,1.90362-18.56023Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M350.84245,645.11151s7.61445-1.42771,7.61445,3.80722a115.23116,115.23116,0,0,0,.9518,12.37349s1.90362,16.65661-4.28313,14.27709-8.56625-19.03612-8.56625-19.03612a7.08933,7.08933,0,0,1,2.85542-3.33133C351.31835,652.25006,350.84245,645.11151,350.84245,645.11151Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><polygon points="172.198 288.424 173.626 306.033 169.819 312.695 159.349 302.701 158.397 289.376 172.198 288.424" fill="#ffb8b8"/><circle cx="163.6319" cy="282.71335" r="11.42168" fill="#ffb8b8"/><polygon points="168.391 305.557 173.15 291.756 181.716 301.274 197.421 361.713 185.523 368.852 180.289 361.237 179.337 371.231 156.017 366.472 154.114 302.701 158.87 296.002 168.391 305.557" fill="#d0cde1"/><polygon points="161.728 373.135 158.873 296.039 152.686 300.798 141.264 308.412 148.879 335.539 151.258 364.093 161.728 373.135" fill="#2f2e41"/><polygon points="144.596 308.888 141.264 308.412 131.746 336.49 112.71 360.286 119.849 367.9 141.74 346.484 149.831 328.876 144.596 308.888" fill="#2f2e41"/><path d="M351.4174,565.59536l-.64933,3.12573s-2.97081,12.20793,1.33475,11.36336,5.4281-11.48008,5.4281-11.48008l-.68754-2.96869Z" transform="translate(-154.84913 -205.35011)" fill="#ffb8b8"/><polygon points="172.406 290.983 195.993 300.322 193.138 328.876 198.849 360.286 193.138 366.472 172.022 295.028 172.406 290.983" fill="#2f2e41"/><path d="M319.079,468.8806l3.35262-1.6763v1.6763l2.23507-1.11753v2.79384s8.38153,6.14645,6.70522,13.41044-1.67631,7.82276-1.67631,7.82276-2.11922-13.81412-10.50074-11.57905-9.05615,2.63876-11.29122,8.78521l-.60636,2.63647S297.84583,469.99814,319.079,468.8806Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><polygon points="192.662 300.322 196.469 567aae300.322 202.656 333.635 202.656 362.665 195.042 361.237 188.855 317.454 192.662 300.322" fill="#2f2e41"/><rect x="3.53501" y="370.77159" width="140.32096" height="97.51118" fill="#567aae"/><path d="M228.54462,595.14827a29.729,29.729,0,1,0,29.729,29.729A29.81642,29.81642,0,0,0,228.54462,595.14827Zm0,8.9187a8.91871,8.91871,0,1,1-8.91871,8.91871,8.94863,8.94863,0,0,1,8.91871-8.91871Zm0,42.93556a21.65737,21.65737,0,0,1-17.83742-9.519c.14293-5.94581,11.89161-9.21886,17.83742-9.21886s17.69448,3.27305,17.8374,9.21886a21.69344,21.69344,0,0,1-17.83741,9.519Z" transform="translate(-154.84913 -205.35011)" fill="#fff"/><rect x="284.18701" y="90.90722" width="176" height="101" fill="#e6e6e6"/><path d="M963.0513,496.58366l.81548-5.25988s4.75311-10.80516.99606-11.38765-6.89084,9.70426-6.89084,9.70426l1.37467,10.98574Z" transform="translate(-154.84913 -205.35011)" fill="#ffb8b8"/><polygon points="846.67 321.051 813.089 314.306 809.187 289.847 799.302 289.084 799.785 320.707 828.962 336.004 846.67 321.051" fill="#575a89"/><polygon points="846.67 321.051 813.089 314.306 809.187 289.847 799.302 289.084 799.785 320.707 828.962 336.004 846.67 321.051" opacity="0.2"/><rect x="910.1623" y="482.06175" width="103.06376" height="8.05267" transform="translate(1768.53923 766.82607) rotate(-180)" fill="#567aae"/><path d="M956.49034,494.78044l.00669-5.32271s3.05587-11.402-.74606-11.40676-5.33608,10.63873-5.33608,10.63873l3.02818,10.64924Z" transform="translate(-154.84913 -205.35011)" fill="#ffb8b8"/><path d="M1000.2023,510.02489l4.60746-1.12311a11.86169,11.86169,0,0,0,11.64163-14.21088h0a15.50416,15.50416,0,0,0-15.48468-15.52363h0A15.50417,15.50417,0,0,0,985.443,494.65194v0A12.32065,12.32065,0,0,0,1000.2023,510.02489Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><polygon points="818.254 381.458 822.005 422.524 828.797 462.833 840.203 462.847 838.732 423.305 832.709 375.393 818.254 381.458" fill="#2f2e41"/><path d="M985.17015,665.90379l-7.6096,4.55277s-12.1681,1.50549-9.89171,5.31029,28.89279,1.55707,28.8947.03629-.748-9.886-2.26874-9.88789Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M1006.77139,583.2605s-.21394,5.87095-5.54811,14.98891l.72505,28.13527,27.33,35.01218-9.89553,8.35184-33.40927-38.06137-8.307-45.63372,10.65879-10.63205Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M1026.99716,661.394s9.12274,1.53224,7.59719,5.33226-5.34945,21.28415-15.23162,18.99057c0,0-4.56232-.00573-3.03773-3.04536a55.0044,55.0044,0,0,1,3.04824-5.31889l.01241-9.885Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><circle cx="840.41522" cy="294.04136" r="11.40581" fill="#ffb8b8"/><polygon points="845.728 301.652 845.712 314.578 833.546 314.563 835.083 301.639 845.728 301.652" fill="#ffb8b8"/><path d="M985.35926,515.34718l3.68652-.9056,11.52122.9247s6.07545,6.09074,5.31316,7.61055-4.611,38.774-4.611,38.774l6.81006,26.62213-24.33429,1.49021-12.16428-1.53605,2.34133-47.90151s-5.30647-12.93326,1.54178-16.7266A29.95429,29.95429,0,0,0,985.35926,515.34718Z" transform="translate(-154.84913 -205.35011)" fill="#575a89"/><polygon points="844.193 313.056 809.978 311.492 802.404 287.911 792.518 288.658 797.801 319.841 828.964 330.526 844.193 313.056" fill="#575a89"/><circle cx="862.43241" cy="278.27937" r="7.35883" fill="#2f2e41"/><path d="M1010.49168,479.67357a7.35536,7.35536,0,0,1,8.807-7.20494A7.3554,7.3554,0,1,0,1014.711,486.331,7.35277,7.35277,0,0,1,1010.49168,479.67357Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><path d="M1004.17862,483.847l-9.92079-1.82669-7.62952,4.78184a11.57336,11.57336,0,0,0-5.33128,11.29456l7.64125-1.93681,1.71106-4.29045,2.03787,3.34024,8.26714,14.45412,8.37-4.55181,5.33322-8.35757Z" transform="translate(-154.84913 -205.35011)" fill="#2f2e41"/><rect x="526.03635" y="245.29674" width="1.99958" height="202.92117" transform="translate(-190.8885 425.93087) rotate(-60.15005)" fill="#fff"/><rect x="425.57556" y="345.75754" width="202.92117" height="1.99958" transform="translate(-257.51689 102.92685) rotate(-29.84553)" fill="#fff"/><rect x="875.53625" y="332.45224" width="1.99979" height="80.61017" transform="translate(-161.69687 523.63263) rotate(-45)" fill="#fff"/><rect x="836.23106" y="371.75743" width="80.61017" height="1.99979" transform="translate(-161.69687 523.63263) rotate(-45)" fill="#fff"/></svg> |