From 3a2e388a33e0c37738deca1128e04a91cca46f8f Mon Sep 17 00:00:00 2001 From: client perkafean Date: Mon, 26 Aug 2024 06:34:56 +0000 Subject: [PATCH] mantab --- package-lock.json | 712 ++++++++++++++++++++++++- package.json | 3 + src/components/Footer.js | 2 +- src/components/Footer.module.css | 3 + src/components/Header.js | 6 +- src/components/Modal.js | 4 + src/components/MusicPlayer.css | 9 +- src/config.js | 2 +- src/helpers/cafeHelpers.js | 5 +- src/helpers/materialMutationHelpers.js | 41 +- src/helpers/transactionHelpers.js | 36 ++ src/pages/CircularDiagram.js | 62 +++ src/pages/Dashboard.js | 2 +- src/pages/MaterialList.js | 50 +- src/pages/Reports.js | 259 +++++++++ src/pages/ScanMeja.js | 9 +- 16 files changed, 1162 insertions(+), 43 deletions(-) create mode 100644 src/pages/CircularDiagram.js create mode 100644 src/pages/Reports.js diff --git a/package-lock.json b/package-lock.json index 4f4532e..bb37436 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "groovebrew-mockup", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/x-charts": "^7.14.0", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -1977,9 +1980,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2308,6 +2311,85 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", @@ -2321,11 +2403,114 @@ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", + "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, "node_modules/@emotion/unitless": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3231,6 +3416,265 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/material": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/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==", + "peer": true + }, + "node_modules/@mui/private-theming": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.6", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/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==" + }, + "node_modules/@mui/x-charts": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.14.0.tgz", + "integrity": "sha512-yjBEGk9fl7rMnCaTqibQEf2Dq8oVMzMVDkEXOztJbb8XG+iC/EtRPOWRahgFVi5xitiKR+lLJ/ezBWzuYK739A==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/system": "^5.16.7", + "@mui/utils": "^5.16.6", + "@mui/x-charts-vendor": "7.14.0", + "@react-spring/rafz": "^9.7.4", + "@react-spring/web": "^9.7.4", + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts-vendor": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts-vendor/-/x-charts-vendor-7.14.0.tgz", + "integrity": "sha512-hhEwqQ5Gt2uEFCIna7OPycyu/CzVlywmH5SIX9O3Rxe/y0muLhafEX2ooOQpopcrgGPmP+2/zTf7cssXPiMmAQ==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@types/d3-color": "^3.1.3", + "@types/d3-delaunay": "^6.0.4", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-scale": "^4.0.8", + "@types/d3-shape": "^3.1.6", + "@types/d3-time": "^3.0.3", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", + "delaunator": "^5.0.1", + "robust-predicates": "^3.0.2" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3370,6 +3814,72 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-spring/animated": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "dependencies": { + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "dependencies": { + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@remix-run/router": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.0.tgz", @@ -4134,6 +4644,50 @@ "@types/node": "*" } }, + "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==" + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + }, + "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==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, "node_modules/@types/eslint": { "version": "8.56.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", @@ -6296,6 +6850,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6933,6 +7495,111 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "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==", + "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==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -7120,6 +7787,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -8727,6 +9402,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -9390,6 +10070,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -9792,6 +10485,14 @@ "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==", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -15828,6 +16529,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", diff --git a/package.json b/package.json index 1e91f63..4c2457d 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/x-charts": "^7.14.0", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/src/components/Footer.js b/src/components/Footer.js index 309599f..9d2935a 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -114,7 +114,7 @@ export default function Footer({ {table.length == 0 && ( QR Code diff --git a/src/components/Footer.module.css b/src/components/Footer.module.css index ea62a43..efd1418 100644 --- a/src/components/Footer.module.css +++ b/src/components/Footer.module.css @@ -1,3 +1,6 @@ +.footerContainer { + margin-top: 40px; +} .footer-rect { height: 75px; background-color: #fff; diff --git a/src/components/Header.js b/src/components/Header.js index 43b6c03..81f4a3d 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -284,7 +284,7 @@ const Header = ({ {HeaderText}
setModal("payment_option")}> payment options + + setModal("reports")}>reports )} @@ -385,6 +387,8 @@ const Header = ({ ))} )} + + setModal("reports")}>reports )} {user.username !== undefined && ( diff --git a/src/components/Modal.js b/src/components/Modal.js index ec9aea8..16617a3 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -10,6 +10,7 @@ import Transaction_success from "../pages/Transaction_success"; import Transaction_failed from "../pages/Transaction_failed"; import MaterialList from "../pages/MaterialList.js"; import MaterialMutationsPage from "../pages/MaterialMutationsPage.js"; +import Reports from "../pages/Reports.js"; const Modal = ({ shop, isOpen, onClose, modalContent }) => { if (!isOpen) return null; @@ -51,6 +52,9 @@ const Modal = ({ shop, isOpen, onClose, modalContent }) => { {modalContent === "update_stock" && ( )} + {modalContent === "reports" && ( + + )}
); diff --git a/src/components/MusicPlayer.css b/src/components/MusicPlayer.css index 39991b2..69e9405 100644 --- a/src/components/MusicPlayer.css +++ b/src/components/MusicPlayer.css @@ -90,8 +90,8 @@ } .expandable-container.expanded { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ position: relative; max-height: 400px; /* Adjust the max-height as needed */ @@ -101,12 +101,11 @@ .expand-button { font-size: 20px; - padding-bottom: 10px; position: relative; left: 0; right: 0; - height: 25px; background-color: rgb(108, 255, 128); + /* background-color: rgb(218 163 99); */ border-radius: 0 0 15px 15px; /* Rounded corners at the bottom */ cursor: pointer; @@ -116,7 +115,9 @@ } .expand-button h5 { + font-weight: 500; margin-top: 0px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.36); } .expand-button:hover { diff --git a/src/config.js b/src/config.js index d2c38df..7e45018 100644 --- a/src/config.js +++ b/src/config.js @@ -1,5 +1,5 @@ // src/config.js -const API_BASE_URL = "https://2jtmkn-5000.csb.app"; // Replace with your actual backend URL +const API_BASE_URL = "https://8h8rx8-5000.csb.app"; // Replace with your actual backend URL export default API_BASE_URL; diff --git a/src/helpers/cafeHelpers.js b/src/helpers/cafeHelpers.js index 0d8b38b..4c9846d 100644 --- a/src/helpers/cafeHelpers.js +++ b/src/helpers/cafeHelpers.js @@ -28,7 +28,7 @@ export async function getOwnedCafes(userId) { } } -export async function createCafe(userId) { +export async function createCafe(cafeName) { try { const response = await fetch(`${API_BASE_URL}/cafe/create-cafe`, { method: "POST", @@ -36,7 +36,8 @@ export async function createCafe(userId) { "Content-Type": "application/json", Authorization: `Bearer ${getAuthToken()}`, }, - body: JSON.stringify({ ownerId: userId }), + body: JSON.stringify({ + name: cafeName }), }); if (!response.ok) { diff --git a/src/helpers/materialMutationHelpers.js b/src/helpers/materialMutationHelpers.js index 575ae31..9cf799d 100644 --- a/src/helpers/materialMutationHelpers.js +++ b/src/helpers/materialMutationHelpers.js @@ -2,21 +2,16 @@ import API_BASE_URL from "../config.js"; // Function to retrieve the authentication token from localStorage function getAuthToken() { - if (localStorage.getItem("auth")) return localStorage.getItem("auth"); - return null; + return localStorage.getItem("auth") || null; } // Helper function to get headers with authentication token -const getHeaders = (method = "GET", body = null) => { - const headers = { - Authorization: `Bearer ${getAuthToken()}`, - "Content-Type": "application/json", - }; - +const getHeaders = () => { return { - method, - headers, - body: body ? JSON.stringify(body) : null, + headers: { + Authorization: `Bearer ${getAuthToken()}`, + "Content-Type": "application/json", + }, }; }; @@ -25,7 +20,14 @@ export const createMaterialMutation = async (materialId, data) => { try { const response = await fetch( `${API_BASE_URL}/mutation/create/${materialId}`, - getHeaders("POST", data) + { + ...getHeaders(), + method: "POST", + body: JSON.stringify({ + newStock: data.get("newStock"), + reason: data.get("reason"), + }), + } ); if (!response.ok) throw new Error("Failed to create material mutation."); return await response.json(); @@ -40,7 +42,10 @@ export const getMaterialMutations = async (cafeId) => { try { const response = await fetch( `${API_BASE_URL}/mutation/get-material-mutations/${cafeId}`, - getHeaders() + { + ...getHeaders(), + method: "GET", + } ); if (!response.ok) throw new Error("Failed to retrieve material mutations."); return await response.json(); @@ -55,7 +60,10 @@ export const getMaterialMutationById = async (mutationId) => { try { const response = await fetch( `${API_BASE_URL}/mutation/get-material-mutation/${mutationId}`, - getHeaders() + { + ...getHeaders(), + method: "GET", + } ); if (!response.ok) throw new Error("Failed to retrieve material mutation."); return await response.json(); @@ -70,7 +78,10 @@ export const getMaterialMutationsByMaterialId = async (materialId) => { try { const response = await fetch( `${API_BASE_URL}/mutation/get-material-mutations-by-material/${materialId}`, - getHeaders() + { + ...getHeaders(), + method: "GET", + } ); if (!response.ok) throw new Error("Failed to retrieve material mutations by material ID."); diff --git a/src/helpers/transactionHelpers.js b/src/helpers/transactionHelpers.js index ed091b7..da355b9 100644 --- a/src/helpers/transactionHelpers.js +++ b/src/helpers/transactionHelpers.js @@ -288,3 +288,39 @@ export const handlePaymentFromGuestDevice = async ( return false; } }; + +// Function to retrieve the authentication token from localStorage +function getAuthToken() { + return localStorage.getItem("auth"); +} +// Helper function to get headers with authentication token +const getHeaders = (method = "GET") => { + const headers = { + Authorization: `Bearer ${getAuthToken()}`, + }; + + // No content-type header needed for FormData; fetch will handle it automatically + if (method !== "POST" && method !== "PUT") { + return { method, headers }; + } + + return { + method, + headers, + }; +}; +export const getFavourite = async (cafeId) => { + const response = await fetch( + `${API_BASE_URL}/transaction/get-favourite/${cafeId}`, + getHeaders() + ); + return response.json(); +}; + +export const getAnalytics = async (cafeId) => { + const response = await fetch( + `${API_BASE_URL}/transaction/get-analytics/${cafeId}`, + getHeaders() + ); + return response.json(); +}; diff --git a/src/pages/CircularDiagram.js b/src/pages/CircularDiagram.js new file mode 100644 index 0000000..21e99da --- /dev/null +++ b/src/pages/CircularDiagram.js @@ -0,0 +1,62 @@ +import React from "react"; + +const CircularDiagram = ({ segments }) => { + const radius = 100; // Radius of the circle + const strokeWidth = 30; // Width of each portion + const circumference = 2 * Math.PI * (radius - strokeWidth / 2); + + // Calculate total value to be displayed + const totalSold = segments.reduce((sum, segment) => sum + segment.value, 0); + + let startOffset = 0; // Initial offset for each segment + + const svgStyles = { + display: "block", + margin: "0 auto", + }; + + return ( + + + {segments.map((segment, index) => { + const { value, color } = segment; + const segmentLength = (circumference * value) / totalSold; + const strokeDashoffset = circumference - startOffset; + + startOffset += segmentLength; + + return ( + + ); + })} + + ); +}; + +export default CircularDiagram; diff --git a/src/pages/Dashboard.js b/src/pages/Dashboard.js index 8452dd1..a704d5f 100644 --- a/src/pages/Dashboard.js +++ b/src/pages/Dashboard.js @@ -113,7 +113,7 @@ const Dashboard = ({ user, setModal }) => { className={styles.rectangle} onClick={() => setIsCreating(true)} > - Create Cafe + + )} diff --git a/src/pages/MaterialList.js b/src/pages/MaterialList.js index a4cdafc..e86ee6e 100644 --- a/src/pages/MaterialList.js +++ b/src/pages/MaterialList.js @@ -23,6 +23,7 @@ const MaterialList = ({ cafeId }) => { const [selectedMaterialId, setSelectedMaterialId] = useState(null); const [currentQuantity, setCurrentQuantity] = useState(0); const [quantityChange, setQuantityChange] = useState(0); + const [sortOrder, setSortOrder] = useState("desc"); useEffect(() => { const fetchMaterials = async () => { @@ -63,7 +64,7 @@ const MaterialList = ({ cafeId }) => { if (materialMutations.length > 0) { const latestMutation = materialMutations.reduce( (latest, current) => - new Date(current.timestamp) > new Date(latest.timestamp) + new Date(current.createdAt) > new Date(latest.createdAt) ? current : latest, materialMutations[0] @@ -75,10 +76,24 @@ const MaterialList = ({ cafeId }) => { } }, [selectedMaterialId, mutations]); + const handleSortChange = (e) => { + setSortOrder(e.target.value); + }; + const filteredMutations = selectedMaterialId ? mutations.filter((mutation) => mutation.materialId === selectedMaterialId) : []; + const sortedMutations = filteredMutations + .filter((mutation) => mutation.materialId === selectedMaterialId) + .sort((a, b) => { + if (sortOrder === "asc") { + return new Date(a.createdAt) - new Date(b.createdAt); + } else { + return new Date(b.createdAt) - new Date(a.createdAt); + } + }); + const handleCreateMaterial = async (e) => { e.preventDefault(); setLoading(true); @@ -166,11 +181,10 @@ const MaterialList = ({ cafeId }) => { try { const newStock = currentQuantity + quantityChange; const formData = new FormData(); - formData.append("materialId", selectedMaterialId); formData.append("newStock", newStock); formData.append("reason", "Stock update"); - await createMaterialMutation(cafeId, formData); + await createMaterialMutation(selectedMaterialId, formData); setQuantityChange(0); const updatedMutations = await getMaterialMutations(cafeId); setMutations(updatedMutations); @@ -188,7 +202,11 @@ const MaterialList = ({ cafeId }) => { const currentMaterial = materials.find( (material) => material.materialId === selectedMaterialId ); - + const formatDate = (timestamp) => { + const date = new Date(timestamp); + return date.toLocaleString(); + }; + return (

Materials List

@@ -299,7 +317,7 @@ const MaterialList = ({ cafeId }) => { -
)} +
+ + +
+ {selectedMaterialId && !loading && (
- {filteredMutations.length > 0 ? ( - filteredMutations.map((mutation) => ( + {sortedMutations.length > 0 ? ( + sortedMutations.map((mutation) => (
-

Mutation ID: {mutation.id}

+

{formatDate(mutation.createdAt)}

Details: {mutation.reason}

-

dari {mutation.oldStock}

-

ke {mutation.newStock}

+

stok {mutation.newStock}

)) ) : ( diff --git a/src/pages/Reports.js b/src/pages/Reports.js new file mode 100644 index 0000000..4cc0e6a --- /dev/null +++ b/src/pages/Reports.js @@ -0,0 +1,259 @@ +import React, { useEffect, useState } from "react"; +import { ThreeDots } from "react-loader-spinner"; +import { getFavourite, getAnalytics } from "../helpers/transactionHelpers.js"; +import CircularDiagram from "./CircularDiagram"; +import styles from "./Transactions.module.css"; + +const RoundedRectangle = ({ bgColor, title, value, percentage }) => { + const containerStyle = { + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + justifyContent: "center", + width: "calc(100% / 2 - 10px)", + maxWidth: "250px", + height: "auto", + borderRadius: "15px", + padding: "20px", + margin: "5px", + textAlign: "left", + fontFamily: "Arial, sans-serif", + boxSizing: "border-box", + }; + + const titleStyle = { + fontWeight: "bold", + marginBottom: "10px", + width: "100%", + }; + + const valueAndPercentageContainerStyle = { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + width: "100%", + }; + + const valueStyle = { + fontSize: "20px", + fontWeight: "bold", + flex: "1", + textAlign: "left", + }; + + const percentageStyle = { + fontSize: "16px", + display: "flex", + alignItems: "center", + textAlign: "right", + }; + + const arrowStyle = { + marginLeft: "5px", + }; + + return ( +
+
{title}
+
+
{value}
+
0 ? "#007bff" : "red", + }} + > + {percentage}% + {percentage > 0 ? "↗" : "↘"} +
+
+
+ ); +}; + +const App = ({ cafeId }) => { + const [favouriteItems, setFavouriteItems] = useState([]); + const [analytics, setAnalytics] = useState({}); + const [loading, setLoading] = useState(true); + const [filter, setFilter] = useState("monthly"); // Default filter is 'monthly' + const [colors, setColors] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + setLoading(true); + const items = await getFavourite(cafeId); + const analyticsData = await getAnalytics(cafeId); + if (items) setFavouriteItems(items); + if (analyticsData) setAnalytics(analyticsData); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [cafeId]); + + useEffect(() => { + const getRandomColor = () => { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + + const r = parseInt(color.substring(1, 3), 16); + const g = parseInt(color.substring(3, 5), 16); + const b = parseInt(color.substring(5, 7), 16); + + return `rgba(${r}, ${g}, ${b}, 1)`; + }; + + const colors = favouriteItems[filter]?.map(() => getRandomColor()) || []; + setColors(colors); + }, [favouriteItems, filter]); + + if (loading) + return ( +
+
+ +
+
+ ); + + const [sold, percentage] = analytics[filter] || [0, 0]; + const filteredItems = favouriteItems[filter] || []; + + const totalSold = filteredItems.reduce((sum, item) => sum + item.sold, 0); + + const segments = filteredItems.map((item, index) => ({ + value: item.sold, + color: colors[index] || "#cccccc", + })); + + return ( +
+

Reports

+
+
+ + + + +
+
+ + {filteredItems[0]?.Item != undefined && ( + + )} + {filteredItems[0]?.Item == undefined && ( + + )} + + +
+
+
+ +
+
+ {filteredItems.map((item, index) => ( +
+ {item.Item.name}: {item.sold} +
+ ))} +
+
+
+
+ ); +}; + +export default App; diff --git a/src/pages/ScanMeja.js b/src/pages/ScanMeja.js index 8262004..7951da3 100644 --- a/src/pages/ScanMeja.js +++ b/src/pages/ScanMeja.js @@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom"; import { QrReader } from "react-qr-reader"; // Import QrReader as named import import styles from "./GuestSideLogin.module.css"; // Import module CSS file for styles -import { getLocalStorage } from "../helpers/localStorageHelpers"; +import { getTableByCode } from "../helpers/tableHelper"; const GuestSideLogin = ({ socket }) => { const navigate = useNavigate(); @@ -15,9 +15,8 @@ const GuestSideLogin = ({ socket }) => { navigate("/" + shopId); }); - const setLoginGuestSide = () => { - const token = getLocalStorage("auth"); - socket.emit("read_qrCode", { qrCode, token }); + const setLoginGuestSide = async () => { + window.location.href = qrCode; }; // Function to handle QR code scan @@ -39,7 +38,7 @@ const GuestSideLogin = ({ socket }) => { }; useEffect(() => { - if (qrCode.length === 11) { + if (qrCode.length === 40) { const timer = setTimeout(() => { setLoginGuestSide(); }, 1000); // Delay of 1 second (1000 milliseconds)