From cabc5be6a3334f6588fa7819d12bba3d20066172 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Jan 2025 16:25:37 +0700 Subject: [PATCH] tpay client --- .gitignore | 2 + package-lock.json | 767 +++++++++++++++++++++++--- package.json | 15 +- public/index.html | 2 +- src/App.js | 25 - src/components/Chart.js | 39 ++ src/components/Header.js | 76 +++ src/components/MemberActivity.js | 163 ++++++ src/components/SideBar.js | 372 +++++++++++++ src/components/StatsCard.js | 24 + src/components/Summary.js | 35 ++ src/components/TransactionList.js | 30 + src/escrowPages/TicketConfirmation.js | 59 ++ src/escrowPages/TransactionHistory.js | 57 ++ src/escrowPages/Transfer.js | 93 ++++ src/index.js | 21 +- src/logo/Logo.jpeg | Bin 0 -> 19199 bytes src/{App.css => pages/Dashboard.css} | 18 + src/pages/Dashboard.js | 17 + src/pages/Login.js | 79 +++ src/pages/ManageAccess.js | 156 ++++++ src/pages/ManageAccount.js | 211 +++++++ src/pages/ManageCredential.js | 113 ++++ src/pages/ManageCurrency.js | 128 +++++ src/pages/ManageGroups.js | 142 +++++ src/pages/ManageMembers.js | 240 ++++++++ src/pages/ManageMenu.js | 142 +++++ src/pages/ManageNotifications.js | 141 +++++ src/pages/ManageTransfers.js | 257 +++++++++ src/pages/ManageWebservice.js | 254 +++++++++ src/pages/MemberKYC.js | 142 +++++ src/pages/Register.js | 141 +++++ src/pages/Setting.js | 77 +++ src/routes/routes.js | 95 ++++ src/style/Chart.css | 13 + src/style/Header.css | 26 + src/style/MemberActivity.css | 18 + src/style/SideBar.css | 29 + src/style/StatsCard.css | 35 ++ src/style/TransactionList.css | 38 ++ 40 files changed, 4186 insertions(+), 106 deletions(-) delete mode 100644 src/App.js create mode 100644 src/components/Chart.js create mode 100644 src/components/Header.js create mode 100644 src/components/MemberActivity.js create mode 100644 src/components/SideBar.js create mode 100644 src/components/StatsCard.js create mode 100644 src/components/Summary.js create mode 100644 src/components/TransactionList.js create mode 100644 src/escrowPages/TicketConfirmation.js create mode 100644 src/escrowPages/TransactionHistory.js create mode 100644 src/escrowPages/Transfer.js create mode 100644 src/logo/Logo.jpeg rename src/{App.css => pages/Dashboard.css} (73%) create mode 100644 src/pages/Dashboard.js create mode 100644 src/pages/Login.js create mode 100644 src/pages/ManageAccess.js create mode 100644 src/pages/ManageAccount.js create mode 100644 src/pages/ManageCredential.js create mode 100644 src/pages/ManageCurrency.js create mode 100644 src/pages/ManageGroups.js create mode 100644 src/pages/ManageMembers.js create mode 100644 src/pages/ManageMenu.js create mode 100644 src/pages/ManageNotifications.js create mode 100644 src/pages/ManageTransfers.js create mode 100644 src/pages/ManageWebservice.js create mode 100644 src/pages/MemberKYC.js create mode 100644 src/pages/Register.js create mode 100644 src/pages/Setting.js create mode 100644 src/routes/routes.js create mode 100644 src/style/Chart.css create mode 100644 src/style/Header.css create mode 100644 src/style/MemberActivity.css create mode 100644 src/style/SideBar.css create mode 100644 src/style/StatsCard.css create mode 100644 src/style/TransactionList.css diff --git a/.gitignore b/.gitignore index 4d29575..81b368c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +.vercel diff --git a/package-lock.json b/package-lock.json index a9887cf..0cc81fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,26 @@ "name": "new-tpay", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.2.1", + "@mui/material": "^6.2.1", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "ajv": "^8.17.1", + "ajv-keywords": "^5.1.0", + "chart.js": "^4.4.7", "react": "^19.0.0", + "react-chartjs-2": "^5.2.0", + "react-circular-progressbar": "^2.1.0", "react-dom": "^19.0.0", + "react-router-dom": "^7.0.2", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@babel/plugin-transform-private-property-in-object": "^7.25.9" } }, "node_modules/@adobe/css-tools": { @@ -2218,6 +2231,152 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "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.3.3", + "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/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/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/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "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/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@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.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "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.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "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/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==" + }, + "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.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -2265,6 +2424,21 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2295,6 +2469,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -2801,11 +2980,248 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "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": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.2.1.tgz", + "integrity": "sha512-U/8vS1+1XiHBnnRRESSG1gvr6JDHdPjrpnW6KEebkAQWBn6wrpbSF/XSZ8/vJIRXH5NyDmMHi4Ro5Q70//JKhA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.2.1.tgz", + "integrity": "sha512-bP0XtW+t5KFL+wjfQp2UctN/8CuWqF1qaxbYuCAsJhL+AzproM8gGOh2n8sNBcrjbVckzDNqaXqxdpn+OmoWug==", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.2.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.2.1.tgz", + "integrity": "sha512-7VlKGsRKsy1bOSOPaSNgpkzaL+0C7iWAVKd2KYyAvhR9fTLJtiAMpq+KuzgEh1so2mtvQERN0tZVIceWMiIesw==", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.2.1", + "@mui/system": "^6.2.1", + "@mui/types": "^7.2.20", + "@mui/utils": "^6.2.1", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^6.2.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" + }, + "node_modules/@mui/private-theming": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.2.1.tgz", + "integrity": "sha512-u1y0gpcfrRRxCcIdVeU5eIvkinA82Q8ft178WUNYuoFQrsOrXdlBdZlRVi+eYuUFp1iXI55Cud7sMZZtETix5Q==", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.2.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.2.1.tgz", + "integrity": "sha512-6R3OgYw6zgCZWFYYMfxDqpGfJA78mUTOIlUDmmJlr60ogVNCrM87X0pqx5TbZ2OwUyxlJxN9qFgRr+J9H6cOBg==", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.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 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.2.1.tgz", + "integrity": "sha512-0lc8CbBP4WAAF+SmGMFJI9bpIyQvW3zvwIDzLsb26FIB/4Z0pO7qGe8mkAl0RM63Vb37899qxnThhHKgAAdy6w==", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.2.1", + "@mui/styled-engine": "^6.2.1", + "@mui/types": "^7.2.20", + "@mui/utils": "^6.2.1", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.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 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.20", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.20.tgz", + "integrity": "sha512-straFHD7L8v05l/N5vcWk+y7eL9JF0C2mtph/y4BPm3gn2Eh61dDwDB65pa8DLss3WJfDXYC7Kx5yjP0EmXpgw==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.2.1.tgz", + "integrity": "sha512-ubLqGIMhKUH2TF/Um+wRzYXgAooQw35th+DPemGrTpgrZHpOgcnUDIDbwsk1e8iQiuJ3mV/ErTtcQrecmlj5cg==", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/types": "^7.2.20", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" + }, "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", @@ -2922,6 +3338,15 @@ } } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3428,6 +3853,11 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/eslint": { "version": "8.56.12", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", @@ -3744,6 +4174,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" + }, "node_modules/@types/q": { "version": "1.5.8", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", @@ -3767,6 +4202,14 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -4328,14 +4771,14 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4358,26 +4801,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -4792,6 +5215,21 @@ "webpack": ">=2" } }, + "node_modules/babel-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/babel-loader/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -4800,6 +5238,11 @@ "ajv": "^6.9.1" } }, + "node_modules/babel-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/babel-loader/node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -5319,6 +5762,17 @@ "node": ">=10" } }, + "node_modules/chart.js": { + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", + "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-types": { "version": "11.2.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", @@ -5414,6 +5868,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", @@ -6082,6 +6544,11 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -6400,6 +6867,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -7259,6 +7735,21 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7304,6 +7795,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7654,6 +8150,21 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/file-loader/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -7662,6 +8173,11 @@ "ajv": "^6.9.1" } }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/file-loader/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -7771,6 +8287,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", @@ -7892,6 +8413,21 @@ } } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -7929,6 +8465,11 @@ "node": ">=10" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", @@ -8391,6 +8932,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", @@ -10354,9 +10908,9 @@ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -12976,6 +13530,23 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-circular-progressbar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-circular-progressbar/-/react-circular-progressbar-2.1.0.tgz", + "integrity": "sha512-xp4THTrod4aLpGy68FX/k1Q3nzrfHUjUe5v6FsdwXBl3YVMwgeXYQKDrku7n/D6qsJA9CuunarAboC2xCiKs1g==", + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -13104,6 +13675,52 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.0.2.tgz", + "integrity": "sha512-m5AcPfTRUcjwmhBzOJGEl6Y7+Crqyju0+TgTQxoS4SO+BkWbhOrcfZNq6wSWdl2BBbJbsAoBUb8ZacOFT+/JlA==", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.0.2.tgz", + "integrity": "sha512-VJOQ+CDWFDGaWdrG12Nl+d7yHtLaurNgAQZVgaIy7/Xd+DojgmYLosFfZdGz1wpxmjJIAkAMVTKWcvkx1oggAw==", + "dependencies": { + "react-router": "7.0.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-router/node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "engines": { + "node": ">=18" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -13176,6 +13793,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -13737,26 +14369,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -13921,6 +14533,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -14597,6 +15214,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -15184,6 +15806,11 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -15769,6 +16396,21 @@ "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -15797,6 +16439,11 @@ "node": ">=4.0" } }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -16043,21 +16690,6 @@ "node": ">=10.0.0" } }, - "node_modules/workbox-build/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/workbox-build/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -16072,11 +16704,6 @@ "node": ">=10" } }, - "node_modules/workbox-build/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "node_modules/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", diff --git a/package.json b/package.json index a27c656..14f31cc 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,26 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.2.1", + "@mui/material": "^6.2.1", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "ajv": "^8.17.1", + "ajv-keywords": "^5.1.0", + "chart.js": "^4.4.7", "react": "^19.0.0", + "react-chartjs-2": "^5.2.0", + "react-circular-progressbar": "^2.1.0", "react-dom": "^19.0.0", + "react-router-dom": "^7.0.2", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", + "start": "react-scripts start eslint-disable-next-line", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" @@ -34,5 +44,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@babel/plugin-transform-private-property-in-object": "^7.25.9" } } diff --git a/public/index.html b/public/index.html index aa069f2..a82a2e7 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,7 @@ 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`. --> - React App + T-Pay Dashboard diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 3784575..0000000 --- a/src/App.js +++ /dev/null @@ -1,25 +0,0 @@ -import logo from './logo.svg'; -import './App.css'; - -function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} - -export default App; diff --git a/src/components/Chart.js b/src/components/Chart.js new file mode 100644 index 0000000..430fef9 --- /dev/null +++ b/src/components/Chart.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Line } from 'react-chartjs-2'; +import { Box, Typography } from '@mui/material'; +import '../style/Chart.css'; + +const ChartBox = () => { + const data = { + labels: ['Jan 01', 'Jan 02', 'Jan 03', 'Jan 04', 'Jan 05', 'Jan 06'], + datasets: [ + { + label: 'Cash In', + data: [50, 75, 200, 125, 150, 175], + backgroundColor: 'rgba(75,192,192,0.4)', + borderColor: 'rgba(75,192,192,1)', + fill: true, // No fill under the line + tension: 0.5, // Line curve + }, + { + label: 'Cash Out', + data: [100, 90, 80, 70, 60, 50], + backgroundColor: 'rgba(255,99,132,0.4)', + borderColor: 'rgba(255,99,132,1)', + fill: true, // No fill under the line + tension: 0.5, // Line curve + }, + ], + }; + + return ( + + + Account Activities + + + + ); +}; + +export default ChartBox; diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..969d7ea --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,76 @@ +import React, { useState } from "react"; +import { + AppBar, + Toolbar, + Typography, + IconButton, + Menu, + MenuItem, + Avatar, +} from "@mui/material"; +import { Mail, AccountCircle } from "@mui/icons-material"; +import "../style/Header.css"; +import { useNavigate } from 'react-router-dom'; + +const Header = () => { + const [anchorEl, setAnchorEl] = useState(null); + const navigate = useNavigate(); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + function logoutBtn() { + localStorage.removeItem("authToken"); + navigate('/login') + } + + const open = Boolean(anchorEl); + + return ( + + + + + + + + + + + + + + Profile + + + My Account + + logoutBtn()}>Logout + + + + ); +}; + +export default Header; diff --git a/src/components/MemberActivity.js b/src/components/MemberActivity.js new file mode 100644 index 0000000..50bd941 --- /dev/null +++ b/src/components/MemberActivity.js @@ -0,0 +1,163 @@ +// src/MyCharts.js +import React from 'react'; +import { Line } from 'react-chartjs-2'; +import { Doughnut } from 'react-chartjs-2'; +import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ArcElement } from 'chart.js'; +import '../style/MemberActivity.css'; +import { + Box, + List, + ListItem, + ListItemText, + Typography, + Divider, +} from "@mui/material"; +import { CircularProgressbar, buildStyles } from "react-circular-progressbar"; +import "react-circular-progressbar/dist/styles.css"; + +// Register Chart.js components +ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ArcElement); + +const MyCharts = () => { + const percentage = 45; + // Level Chart (Line Chart) Data + const levelData = { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'Level Progress', + data: [20, 40, 60, 80, 100, 90, 70], + fill: false, + borderColor: 'rgb(75, 192, 192)', + tension: 0.1, + }, + ], + }; + + // Circle Chart (Doughnut Chart) Data + const circleData = { + labels: ['Completed', 'Remaining'], + datasets: [ + { + label: 'Completion', + data: [75, 25], + backgroundColor: ['rgb(75, 192, 192)', 'rgb(192, 75, 75)'], + borderColor: 'rgb(255, 255, 255)', + borderWidth: 1, + }, + ], + }; + + // Performance Chart (Bar Chart) Data + // const performanceData = { + // labels: ['Q1', 'Q2', 'Q3', 'Q4'], + // datasets: [ + // { + // label: 'Performance', + // data: [50, 70, 90, 60], + // backgroundColor: 'rgb(75, 192, 192)', + // borderColor: 'rgb(0, 123, 255)', + // borderWidth: 1, + // }, + // ], + // }; + + // Chart Options + const options = { + responsive: true, + plugins: { + legend: { + position: 'top', + }, + }, + }; + + return ( +
+
+ +

Level Chart

+ +
+
+
+ +

Circle Chart

+ +
+
+
+

Performance Chart

+ {/* */} + + {/* Sidebar Menu */} + + + {[ + "Settings", + "Subscription", + "Auto Renewal", + "Achievements", + "Logout", + ].map((text, index) => ( + + + + + {index === 3 && } {/* Divider after "Achievements" */} + + ))} + + + + {/* Active User Section */} + + + Active User + + + + + + {`${percentage}%`} + + + +
+
+ ); +}; + +export default MyCharts; \ No newline at end of file diff --git a/src/components/SideBar.js b/src/components/SideBar.js new file mode 100644 index 0000000..bf8e2ea --- /dev/null +++ b/src/components/SideBar.js @@ -0,0 +1,372 @@ +import React, { useState } from 'react'; +import { + Drawer, + List, + ListItem, + ListItemText, + Accordion, + AccordionSummary, + AccordionDetails, + Typography, + Button, + // Divider, + Box, + Tooltip, + Avatar +} from '@mui/material'; + +import SettingsIcon from "@mui/icons-material/Settings"; +import HelpIcon from "@mui/icons-material/Help"; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import InfoIcon from "@mui/icons-material/Info"; +import Logout from "@mui/icons-material/Logout"; +import { useNavigate } from 'react-router-dom'; + +const Sidebar = () => { + const [userRole, setUserRole] = useState(''); + const navigate = useNavigate(); + const adminMenu = [ + { + title: 'Group', + options: [ + { + title: 'Manage Groups', + path: '/manage-groups' + } + ], + }, + { + title: 'Member', + options: [ + { + title: 'Manage Members', + path: '/manage-members' + }, + { + title: 'KYC', + path: '/manage-member-kyc' + } + ], + }, + { + title: 'Access', + options: [ + { + title: 'Manage Access Type', + path: '/manage-access' + }, + { + title: 'Create Member Credential', + path: '/manage-member-credential' + } + ], + }, + { + title: 'Account', + options: [ + { + title: 'Manage Account', + path: '/manage-accounts' + }, + { + title: 'Manage Currency', + path: '/manage-currency' + } + ], + }, + { + title: 'Transfer Type', + options: [ + { + title: 'Manage Transfer Type', + path: '/manage-transfers' + } + ], + }, + { + title: 'Notification', + options: [ + { + title: 'Manage Notification', + path: '/manage-notifications' + } + ], + }, + { + title: 'Menu', + options: [ + { + title: 'Wellcome', + }, + { + title: 'Menu Category', + }, + { + title: 'Manage Menu', + path: '/manage-menu' + } + ], + }, + { + title: 'Message', + options: [ + { + title: 'Inbox', + } + ], + }, + { + title: 'Webservice', + options: [ + { + title: 'Manage Webservice', + path: '/manage-webservice' + } + ], + }, + { + title: 'Setting', + options: [ + { + title: 'Setting', + path: '/setting' + } + ], + }, + ]; + + const esCrowMenu = [ + { + title: 'Home', + options: [ + { + title: 'Dashboard', + path: '/' + }, + { + title: 'Transaction History', + path: '/transaction-history' + } + ], + }, + { + title: 'Member', + options: [ + { + title: 'Manage Members', + path: '/manage-members' + }, + ], + }, + { + title: 'Message', + options: [ + { + title: 'Inbox', + } + ], + }, + { + title: 'Setting', + options: [ + { + title: 'Setting', + path: '/setting' + } + ], + }, + ] + + const escrowSubMenu = [ + { + title: 'Transaction', + options: [ + { + title: 'Transfer', + path: '/transfer' + }, + { + title: 'Ticket Confirmation', + path: '/ticket-confirmation' + } + ], + } + ] + + const tdsMenu = [ + { + title: 'Home', + path: '/' + }, + { + title: 'Transaction Report', + options: [ + { + title: 'Agent Balance', + path: '/agent-balance' + }, + { + title: 'Deposit Report', + path: '/deposit-report' + }, + { + title: 'Topup', + path: '/topup' + }, + ], + }, + { + title: 'Operation', + options: [ + { + title: 'Topup Approval', + path: '/topup-approval' + }, + { + title: 'Topup Request', + path: '/topup-request' + }, + { + title: 'Transfer', + path: '/transfer' + }, + ], + }, + { + title: 'User Management', + options: [ + { + title: 'Agent Registered', + path: '/agent' + }, + { + title: 'Supervisor Registered', + path: '/supervisor' + } + ], + }, + ] + + function roleMenu() { + setUserRole('escrow') + if (userRole === 'admin') return adminMenu + if (userRole === 'escrow') return esCrowMenu + if (userRole === 'tds') return tdsMenu + return [] + } + + function logoutBtn() { + localStorage.removeItem("authToken"); + navigate('/login'); + } + + return ( + + + + + {/* */} + + { + userRole === 'escrow' ? ( + escrowSubMenu} navigate={navigate} label={`Transaction`}/> + ) : ('') + } + + + {/* FOOTER */} + + + + + + + + + + + + + + + + + ); +}; + +function ListOfMenus({roleMenu, navigate, label}) { + const [expanded, setExpanded] = useState(false); + const handleExpand = (index, menu) => { + if (menu.options) return setExpanded((prevExpanded) => (prevExpanded === index ? false : index)); + }; + + function onClickParent(menu) { + if (menu.options) return false + return navigate(menu.path) + } + + return ( + <> +

{label}

+ + {roleMenu().map((menuItem, index) => ( + handleExpand(index, menuItem)} + sx={{ + backgroundColor: 'inherit', + color: '#fff', + boxShadow: 'none', + }} + > + : ''}> + + onClickParent(menuItem)} ml={1}>{menuItem.title} + + + {menuItem.options && menuItem.options.map((option, subIndex) => ( + + + navigate(option.path)} color='wheat' style={{ textAlign: 'left' }}>{option.title} + + + ))} + + + ))} + + + ) +} + +export default Sidebar; diff --git a/src/components/StatsCard.js b/src/components/StatsCard.js new file mode 100644 index 0000000..1bf1d04 --- /dev/null +++ b/src/components/StatsCard.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Card, CardContent, Typography } from '@mui/material'; +import '../style/StatsCard.css' + +const StatsCard = ({ title, value, growth }) => { + return ( + + + + {title} + + {value} + = 0 ? 'green' : 'red' }} + > + {growth}% From last week + + + + ); +}; + +export default StatsCard; diff --git a/src/components/Summary.js b/src/components/Summary.js new file mode 100644 index 0000000..bf79d44 --- /dev/null +++ b/src/components/Summary.js @@ -0,0 +1,35 @@ +import StatsCard from "../components/StatsCard"; +import ChartBox from "../components/Chart"; +import TransactionList from "../components/TransactionList"; +import MemberActivity from "../components/MemberActivity"; +import { Box, Grid } from "@mui/material"; + +export default function Summary() { + return ( + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+ ) +} \ No newline at end of file diff --git a/src/components/TransactionList.js b/src/components/TransactionList.js new file mode 100644 index 0000000..5d69b70 --- /dev/null +++ b/src/components/TransactionList.js @@ -0,0 +1,30 @@ +import React from 'react'; +import { List, ListItem, ListItemText, Box, LinearProgress, Typography } from '@mui/material'; +import '../style/TransactionList.css'; + +const TransactionList = () => { + const transactions = [ + { type: 'Member Transfer', percentage: 60 }, + { type: 'Bill Payment', percentage: 30 }, + { type: 'Topup', percentage: 20 }, + { type: 'Purchase', percentage: 10 }, + ]; + + return ( + + + Top Transactions + + + {transactions.map((transaction, index) => ( + + + + + ))} + + + ); +}; + +export default TransactionList; diff --git a/src/escrowPages/TicketConfirmation.js b/src/escrowPages/TicketConfirmation.js new file mode 100644 index 0000000..52fae68 --- /dev/null +++ b/src/escrowPages/TicketConfirmation.js @@ -0,0 +1,59 @@ +import React, { useState } from "react"; +import { + TextField, + Button, + Box, + Typography, + Paper, +} from "@mui/material"; + +const TicketConfirmationPage = () => { + // State for form fields + const [ticketId, setTicketId] = useState(""); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (ticketId) { + console.log("Registered with:", { ticketId }); + } else { + alert("Please fill in all fields."); + } + }; + + return ( + + + Ticket Confirmation + + + + Confirm Ticket + + + +
+ + setTicketId(e.target.value)} + required + /> + + + + + + +
+
+
+
+
+ ); +}; + +export default TicketConfirmationPage; \ No newline at end of file diff --git a/src/escrowPages/TransactionHistory.js b/src/escrowPages/TransactionHistory.js new file mode 100644 index 0000000..c83caf2 --- /dev/null +++ b/src/escrowPages/TransactionHistory.js @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { Box, Typography, Button, Grid, Card, CardContent } from '@mui/material'; + +export default function TransactionHistory() { + const accounts = [ + { + title: "Merchant Account", + description: "Rekening Merchant" + }, + { + title: "Deposit Account", + description: "Rekening Deposit" + }, + { + title: "Cash out/in account to bank", + description: "Pooling account to maintain cash in/out member to bank" + } + ]; + + return ( + + + Transaction History + + + + Select Account + + + {accounts.map((account, index) => ( + + + + + + {account.title} + + + + {account.description} + + + + + + + + + + ))} + + + + ); +} diff --git a/src/escrowPages/Transfer.js b/src/escrowPages/Transfer.js new file mode 100644 index 0000000..8636527 --- /dev/null +++ b/src/escrowPages/Transfer.js @@ -0,0 +1,93 @@ +import React, { useState } from "react"; +import { + TextField, + Button, + Box, + Typography, + Paper, +} from "@mui/material"; + +const TransferPage = () => { + // State for form fields + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (name && email) { + // Handle registration logic, like calling an API to create the user + console.log("Registered with:", { name, email }); + } else { + alert("Please fill in all fields."); + } + }; + + return ( + + + Transaction + + + + Transfer + + + +
+ + setName(e.target.value)} + required + /> + + + setName(e.target.value)} + required + /> + + + setEmail(e.target.value)} + type="text" + required + /> + + + setEmail(e.target.value)} + type="text" + required + /> + + + + + + +
+
+
+
+
+ ); +}; + +export default TransferPage; \ No newline at end of file diff --git a/src/index.js b/src/index.js index d563c0f..0f58506 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,17 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; -import App from './App'; -import reportWebVitals from './reportWebVitals'; +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./routes/routes"; +import reportWebVitals from "./reportWebVitals"; +import { BrowserRouter } from "react-router-dom"; -const root = ReactDOM.createRoot(document.getElementById('root')); +const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - - - + + + + + ); // If you want to start measuring performance in your app, pass a function diff --git a/src/logo/Logo.jpeg b/src/logo/Logo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5f2edf383344d2c82d52e770cb7a13f9c858a202 GIT binary patch literal 19199 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

2n;+I*&BZWXA=F9C%gY2kiQwEv^x)mt$ zA?-<(jSt~nCgE7u5E{TIJz!6slgHlI=xQccJx9ReMPUV~(nJn{TEr7V%8Oh#uCz#q z=p$iC>kwe#)VZvFZwiQQ-?&f#1&{KT6x7$=o>FqWaB5NFW7gF=UN=}2!aQR+vRd9g z^}MNeRJG|_#+B9g*cAa?0%$77TA&?jXyryljNlfzDt(bX z`zlYn8O>a|_)(k;QKoA}zxz-zF9MGf+5Z5*)(_xcK~ZR|{>msaP{AhmiJ$-gFc1DW K|Na020RP$4RNd$R literal 0 HcmV?d00001 diff --git a/src/App.css b/src/pages/Dashboard.css similarity index 73% rename from src/App.css rename to src/pages/Dashboard.css index 74b5e05..6329407 100644 --- a/src/App.css +++ b/src/pages/Dashboard.css @@ -36,3 +36,21 @@ transform: rotate(360deg); } } + +.main-content { + margin-left: 250px; + padding: 20px; + background-color: #f9f9f9; + min-height: 100vh; +} + +.stats { + display: flex; + gap: 20px; + margin-bottom: 20px; +} + +.stats-card { + flex: 1; +} + diff --git a/src/pages/Dashboard.js b/src/pages/Dashboard.js new file mode 100644 index 0000000..e995906 --- /dev/null +++ b/src/pages/Dashboard.js @@ -0,0 +1,17 @@ +// import logo from "./logo.svg"; +import "./Dashboard.css"; +import Chart from "chart.js/auto"; +import { CategoryScale } from "chart.js"; +import Summary from "../components/Summary"; + +Chart.register(CategoryScale); + +function Dasboard() { + return ( +

+ +
+ ); +} + +export default Dasboard; diff --git a/src/pages/Login.js b/src/pages/Login.js new file mode 100644 index 0000000..6157f1e --- /dev/null +++ b/src/pages/Login.js @@ -0,0 +1,79 @@ +import React, { useState } from "react"; +import { TextField, Button, Box, Typography, Grid, Paper } from "@mui/material"; +import {Link, useNavigate } from 'react-router-dom'; + +const LoginPage = () => { + // State for email and password + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const navigate = useNavigate(); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (email && password) { + // Handle login logic here, for example, API call + console.log("Logged in with:", { email, password }); + localStorage.setItem('authToken', email) + navigate('/'); + } else { + alert("Please fill in both fields."); + } + }; + + return ( + + + + + Login + +
+ + setEmail(e.target.value)} + type="email" + required + /> + + + setPassword(e.target.value)} + type="password" + required + /> + + + + + +
+
+
+
+ ); +}; + +export default LoginPage; \ No newline at end of file diff --git a/src/pages/ManageAccess.js b/src/pages/ManageAccess.js new file mode 100644 index 0000000..c282ae6 --- /dev/null +++ b/src/pages/ManageAccess.js @@ -0,0 +1,156 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'name', label: 'Name', minWidth: 100 }, + { + id: 'internalName', + label: 'Internal Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'description', + label: 'Description', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 5, + "data": [ + { + "description": "Default PIN Credential", + "id": 1, + "internalName": "pin_credential", + "name": "PIN Credential" + }, + { + "description": "Partner Secret Auth Credential", + "id": 2, + "internalName": "secret_auth", + "name": "Secret Auth" + }, + { + "description": "Partner API Key", + "id": 3, + "internalName": "api_key", + "name": "APIKey" + }, + { + "description": "Web Access Credential", + "id": 4, + "internalName": "web_credential", + "name": "Web Credential" + }, + { + "description": "One To Many Transfers", + "id": 5, + "internalName": "otm_tpay", + "name": "OTM TPay" + } + ], + "recordsTotal": 5 +}; + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Access + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageAccount.js b/src/pages/ManageAccount.js new file mode 100644 index 0000000..01b74a2 --- /dev/null +++ b/src/pages/ManageAccount.js @@ -0,0 +1,211 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'name', label: 'Name', minWidth: 100 }, + { + id: 'description', + label: 'Description', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'systemAccount', + label: 'System Account', + minWidth: 170, + align: 'right', + }, + { id: 'createdDate', label: 'Created Date', minWidth: 100 }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +function generateData(data, column) { + if (column === 'systemAccount') return data ? 'true' : 'false'; + return data; +} + +const rows = { + "recordsFiltered": 5, + "data": [ + { + "createdDate": "2019-12-05T09:18:06.000+0000", + "creditLimit": null, + "currency": null, + "description": "Rekening Member eMoney", + "formattedCreatedDate": "2019-12-05 18:18:06", + "formattedCreditLimit": null, + "formattedLowerCreditLimit": null, + "formattedUpperCreditLimit": null, + "group": null, + "id": 1, + "lowerCreditLimit": null, + "name": "eMoney Account", + "systemAccount": false, + "upperCreditLimit": null + }, + { + "createdDate": "2019-12-11T07:44:29.000+0000", + "creditLimit": null, + "currency": null, + "description": "Topup Account", + "formattedCreatedDate": "2019-12-11 16:44:29", + "formattedCreditLimit": null, + "formattedLowerCreditLimit": null, + "formattedUpperCreditLimit": null, + "group": null, + "id": 24, + "lowerCreditLimit": null, + "name": "Topup Account", + "systemAccount": true, + "upperCreditLimit": null + }, + { + "createdDate": "2019-12-05T09:19:19.000+0000", + "creditLimit": null, + "currency": null, + "description": "Rekening Merchant", + "formattedCreatedDate": "2019-12-05 18:19:19", + "formattedCreditLimit": null, + "formattedLowerCreditLimit": null, + "formattedUpperCreditLimit": null, + "group": null, + "id": 39, + "lowerCreditLimit": null, + "name": "Merchant Account", + "systemAccount": false, + "upperCreditLimit": null + }, + { + "createdDate": "2019-12-05T09:19:25.000+0000", + "creditLimit": null, + "currency": null, + "description": "Rekening Deposit", + "formattedCreatedDate": "2019-12-05 18:19:25", + "formattedCreditLimit": null, + "formattedLowerCreditLimit": null, + "formattedUpperCreditLimit": null, + "group": null, + "id": 40, + "lowerCreditLimit": null, + "name": "Deposit Account", + "systemAccount": false, + "upperCreditLimit": null + }, + { + "createdDate": "2021-04-13T16:45:13.000+0000", + "creditLimit": null, + "currency": null, + "description": "Pooling account to maintain cash in/out member to bank", + "formattedCreatedDate": "2021-04-14 01:45:13", + "formattedCreditLimit": null, + "formattedLowerCreditLimit": null, + "formattedUpperCreditLimit": null, + "group": null, + "id": 41, + "lowerCreditLimit": null, + "name": "Cash out/in account to bank", + "systemAccount": true, + "upperCreditLimit": null + } + ], + "recordsTotal": 5 +}; + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Account + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : generateData(value, column.id) + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageCredential.js b/src/pages/ManageCredential.js new file mode 100644 index 0000000..cb45f8e --- /dev/null +++ b/src/pages/ManageCredential.js @@ -0,0 +1,113 @@ +import React, { useState } from "react"; +import { + TextField, + Button, + Box, + Typography, + Paper, + InputLabel, + Select, + MenuItem +} from "@mui/material"; + +const SettingPage = () => { + // State for form fields + const [accessType, setAccessType] = useState(""); + const [username, setUsername] = useState(""); + const [credential, setCredential] = useState(""); + const [confirmCredential, setConfirmCredential] = useState(""); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (credential !== confirmCredential) { + alert("Credentials do not match!"); + return; + } + if (accessType && username && credential && setConfirmCredential) { + // Handle registration logic, like calling an API to create the user + console.log("Registered with:", { accessType, username, credential }); + } else { + alert("Please fill in all fields."); + } + }; + + return ( + + Access + + + + Manage Member Credential +
+ + Access Type + + {/* setAccessType(e.target.value)} + required + /> */} + + + setUsername(e.target.value)} + required + /> + + + setCredential(e.target.value)} + type="password" + required + /> + + + setConfirmCredential(e.target.value)} + type="password" + required + /> + + + + + + +
+
+
+
+
+ ); +}; + +export default SettingPage; \ No newline at end of file diff --git a/src/pages/ManageCurrency.js b/src/pages/ManageCurrency.js new file mode 100644 index 0000000..9e36953 --- /dev/null +++ b/src/pages/ManageCurrency.js @@ -0,0 +1,128 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'name', label: 'Name', minWidth: 100 }, + { id: 'code', label: 'Code', minWidth: 100 }, + { id: 'prefix', label: 'Prefix', minWidth: 100 }, + { id: 'trailer', label: 'Trailer', minWidth: 100 }, + { id: 'format', label: 'Format', minWidth: 100 }, + { id: 'grouping', label: 'Grouping Separator', minWidth: 100 }, + { id: 'decimal', label: 'Decimal Separator', minWidth: 100 }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 1, + "data": [ + { + "code": "USD", + "decimal": ".", + "format": "#,##0.00", + "grouping": ",", + "id": 2, + "name": "Dollar", + "prefix": "$", + "trailer": "" + } + ], + "recordsTotal": 1 +}; + +export default function ManageCurrency() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Currency + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageGroups.js b/src/pages/ManageGroups.js new file mode 100644 index 0000000..0a8c192 --- /dev/null +++ b/src/pages/ManageGroups.js @@ -0,0 +1,142 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'createdDate', label: 'Created Date', minWidth: 100 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'description', + label: 'Description', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +function createData(id, name, description, population, size) { + const today = new Date(); + return { id, name, description, population, size, createdDate: today.toString()}; +} + +const rows = [ + createData(1,'India', 'IN', 1324171354, 3287263), + createData(2,'China', 'CN', 1403500365, 9596961), + createData(3,'Italy', 'IT', 60483973, 301340), + createData(4,'United States', 'US', 327167434, 9833520), + createData(5,'Canada', 'CA', 37602103, 9984670), + createData(6,'Australia', 'AU', 25475400, 7692024), + createData(7,'Germany', 'DE', 83019200, 357578), + createData(8,'Ireland', 'IE', 4857000, 70273), + createData(9,'Mexico', 'MX', 126577691, 1972550), + createData(10,'Japan', 'JP', 126317000, 377973), + createData(11,'France', 'FR', 67022000, 640679), + createData(12,'United Kingdom', 'GB', 67545757, 242495), + createData(13,'Russia', 'RU', 146793744, 17098246), + createData(14,'Nigeria', 'NG', 200962417, 923768), + createData(15,'Brazil', 'BR', 210147125, 8515767), +]; + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Group + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageMembers.js b/src/pages/ManageMembers.js new file mode 100644 index 0000000..a66d2ff --- /dev/null +++ b/src/pages/ManageMembers.js @@ -0,0 +1,240 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'username', label: 'Username', minWidth: 100 }, + { + id: 'group', + label: 'Group', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'name', + label: 'Name', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'email', + label: 'Email', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'createdDate', + label: 'Created Date', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 35023, + "data": [ + { + "createdDate": "2024-12-29 15:56:00", + "groupID": 36871, + "name": "Tomas Pinto Amaral", + "id": 36871, + "msisdn": "67074546696", + "email": "tomasamaral1302@gmail.com", + "username": "67074546696", + "group": "REGULER" + }, + { + "createdDate": "2024-12-28 23:15:00", + "groupID": 36870, + "name": "Eleioterio Jeronimo Dos Santos Belmonte", + "id": 36870, + "msisdn": "67074677364", + "email": "Ellebambros6@gmail.con", + "username": "67074677364", + "group": "REGULER" + }, + { + "createdDate": "2024-12-28 06:52:00", + "groupID": 36869, + "name": "Joao de Brito ximenes ", + "id": 36869, + "msisdn": "67073650842", + "email": "ximenesjhon42@gmail.com", + "username": "67073650842", + "group": "REGULER" + }, + { + "createdDate": "2024-12-28 03:44:00", + "groupID": 36868, + "name": "nelson da costa moniz calau", + "id": 36868, + "msisdn": "67078525938", + "email": "calaunelson842@gmail.com", + "username": "67078525938", + "group": "REGULER" + }, + { + "createdDate": "2024-12-27 10:35:00", + "groupID": 36867, + "name": "Arcenia Maria Martins", + "id": 36867, + "msisdn": "67078601536", + "email": "arceniamartins04@gmail.com", + "username": "67078601536", + "group": "REGULER" + }, + { + "createdDate": "2024-12-26 22:29:00", + "groupID": 36866, + "name": "Yakov", + "id": 36866, + "msisdn": "79604742286", + "email": "makarevichyakov2004@gmail.com", + "username": "79604742286", + "group": "REGULER" + }, + { + "createdDate": "2024-12-23 15:44:00", + "groupID": 36865, + "name": "Juliao Baptista", + "id": 36865, + "msisdn": "67078248108", + "email": "juliao.baptista.1988@gmail.com", + "username": "67078248108", + "group": "REGULER" + }, + { + "createdDate": "2024-12-20 15:48:00", + "groupID": 36864, + "name": "Celicia A. Lina da Silva Pereira", + "id": 36864, + "msisdn": "67073565079", + "email": "abulinadasilva@gamail.com", + "username": "67073565079", + "group": "PREMIUM" + }, + { + "createdDate": "2024-12-19 23:26:00", + "groupID": 36863, + "name": "Noe Afonso guterres", + "id": 36863, + "msisdn": "67077775543", + "email": "noeguterres9@gmail.com", + "username": "67077775543", + "group": "REGULER" + }, + { + "createdDate": "2024-12-19 20:08:00", + "groupID": 36862, + "name": "Leandro Simões De Araújo ", + "id": 36862, + "msisdn": "67073854248", + "email": "leoandroaraujo016@gmail.com", + "username": "67073854248", + "group": "REGULER" + } + ], + "recordsTotal": 35023 +}; + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Member + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageMenu.js b/src/pages/ManageMenu.js new file mode 100644 index 0000000..ee70c06 --- /dev/null +++ b/src/pages/ManageMenu.js @@ -0,0 +1,142 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'createdDate', label: 'Created Date', minWidth: 100 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'description', + label: 'Description', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +function createData(id, name, description, population, size) { + const today = new Date(); + return { id, name, description, population, size, createdDate: today.toString()}; +} + +const rows = [ + createData(1,'India', 'IN', 1324171354, 3287263), + createData(2,'China', 'CN', 1403500365, 9596961), + createData(3,'Italy', 'IT', 60483973, 301340), + createData(4,'United States', 'US', 327167434, 9833520), + createData(5,'Canada', 'CA', 37602103, 9984670), + createData(6,'Australia', 'AU', 25475400, 7692024), + createData(7,'Germany', 'DE', 83019200, 357578), + createData(8,'Ireland', 'IE', 4857000, 70273), + createData(9,'Mexico', 'MX', 126577691, 1972550), + createData(10,'Japan', 'JP', 126317000, 377973), + createData(11,'France', 'FR', 67022000, 640679), + createData(12,'United Kingdom', 'GB', 67545757, 242495), + createData(13,'Russia', 'RU', 146793744, 17098246), + createData(14,'Nigeria', 'NG', 200962417, 923768), + createData(15,'Brazil', 'BR', 210147125, 8515767), +]; + +export default function ManageMenus() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Menu + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageNotifications.js b/src/pages/ManageNotifications.js new file mode 100644 index 0000000..2043f1a --- /dev/null +++ b/src/pages/ManageNotifications.js @@ -0,0 +1,141 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'moduleURL', + label: 'Destination Module', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 2, + "data": [ + { + "enabled": false, + "id": 1, + "moduleURL": "https://tpay.tl/middle-tpay/notif/sender", + "name": "notifSender", + "notificationType": null, + "transferTypeID": null + }, + { + "enabled": false, + "id": 2, + "moduleURL": "https://tpay.tl/middle-tpay/notif/receiver", + "name": "notifBenefeciary", + "notificationType": null, + "transferTypeID": null + } + ], + "recordsTotal": 2 +} + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Notification + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageTransfers.js b/src/pages/ManageTransfers.js new file mode 100644 index 0000000..9a2ee79 --- /dev/null +++ b/src/pages/ManageTransfers.js @@ -0,0 +1,257 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { id: 'fromAccountName', label: 'From Account', minWidth: 100 }, + { id: 'toAccountName', label: 'To Account', minWidth: 100 }, + { + id: 'description', + label: 'Description', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 21, + "data": [ + { + "description": "Transaction for Payment Mytelkomcel", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 58, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Payment Mytelkomcel", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Disburse transaction EDTL from user to Agent", + "fromAccountName": "Merchant Account", + "fromAccounts": 39, + "id": 57, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.00, + "name": "Disburse transaction EDTL", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Transaction for payment EDTL", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 56, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Sosa Token EDTL", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Disburs myloja to agent", + "fromAccountName": "Merchant Account", + "fromAccounts": 39, + "id": 55, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Disburs myloja to agent", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Purchase Pulsa", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 54, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.00, + "name": "Rekarga Pulsa", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Transaction for payment MyLoja", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 53, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Payment MyLoja", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Cashout Member to Bank Account", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 52, + "maxAmount": 300.00, + "maxCount": 10, + "minAmount": 1.00, + "name": "Dada Osan P24", + "otpThreshold": 0.00, + "toAccountName": "Cash out/in account to bank", + "toAccounts": 41 + }, + { + "description": "Topup Member e-money from Bank", + "fromAccountName": "Cash out/in account to bank", + "fromAccounts": 41, + "id": 51, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 1.00, + "name": "Top up P24", + "otpThreshold": 0.00, + "toAccountName": "eMoney Account", + "toAccounts": 1 + }, + { + "description": "Transaction for buying voucher games ", + "fromAccountName": "eMoney Account", + "fromAccounts": 1, + "id": 50, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Payment GamesTL", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + }, + { + "description": "Partner disburse to agent or driver account", + "fromAccountName": "Merchant Account", + "fromAccounts": 39, + "id": 49, + "maxAmount": 0.00, + "maxCount": 0, + "minAmount": 0.01, + "name": "Disburse agent or driver", + "otpThreshold": 0.00, + "toAccountName": "Merchant Account", + "toAccounts": 39 + } + ], + "recordsTotal": 21 +}; + +export default function ManageGroups() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Transfer Type + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/ManageWebservice.js b/src/pages/ManageWebservice.js new file mode 100644 index 0000000..a377f96 --- /dev/null +++ b/src/pages/ManageWebservice.js @@ -0,0 +1,254 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'username', + label: 'Username', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'active', + label: 'Enabled', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'secureTransaction', + label: 'Secure', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +const rows = { + "recordsFiltered": 13, + "data": [ + { + "active": true, + "group": null, + "hash": "edtl", + "id": 20, + "name": "dw-tpay-edtl", + "password": "123456", + "permissionID": null, + "secureTransaction": true, + "username": "doku_tpay_edtl" + }, + { + "active": true, + "group": null, + "hash": "scheduler", + "id": 19, + "name": "scheduler", + "password": "123456", + "permissionID": null, + "secureTransaction": false, + "username": "scheduler" + }, + { + "active": true, + "group": null, + "hash": "YL29DDQ66XZJ67TH", + "id": 18, + "name": "tpay-biller-nontransactional", + "password": "tpay-biller", + "permissionID": null, + "secureTransaction": false, + "username": "tpay-biller-nontransactional" + }, + { + "active": true, + "group": null, + "hash": "YL29DDQ66XZJ67TH", + "id": 17, + "name": "tpay-biller", + "password": "tpay-biller", + "permissionID": null, + "secureTransaction": true, + "username": "tpay-biller" + }, + { + "active": true, + "group": null, + "hash": "p24", + "id": 16, + "name": "dw-tpay-p24-nontransactional", + "password": "123456", + "permissionID": null, + "secureTransaction": false, + "username": "dokup24tpaynontransactional" + }, + { + "active": true, + "group": null, + "hash": "p24", + "id": 15, + "name": "dw-tpay-p24", + "password": "123456", + "permissionID": null, + "secureTransaction": true, + "username": "dokup24tpay" + }, + { + "active": true, + "group": null, + "hash": "doku", + "id": 14, + "name": "dw-mobileapi-tpay-non-transactional", + "password": "123456", + "permissionID": null, + "secureTransaction": false, + "username": "doku_dev_non" + }, + { + "active": true, + "group": null, + "hash": "dokusimpel", + "id": 13, + "name": "simpel-ads-tpay", + "password": "simpel", + "permissionID": null, + "secureTransaction": false, + "username": "simpel" + }, + { + "active": true, + "group": null, + "hash": "doku", + "id": 12, + "name": "dw-mobileapi-tpay", + "password": "123456", + "permissionID": null, + "secureTransaction": true, + "username": "doku_dev" + }, + { + "active": true, + "group": null, + "hash": "MW7389B8ikj83990", + "id": 11, + "name": "Middleware Bank", + "password": "123456", + "permissionID": null, + "secureTransaction": false, + "username": "mwbank" + } + ], + "recordsTotal": 13 +} + +export default function ManageWebservice() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + function generateData(data, column) { + if (column === 'secureTransaction' || column === 'active') return data ? 'true' : 'false'; + return data; + } + + return ( + + Manage Webservice + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows.data + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : generateData(value, column.id) + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/MemberKYC.js b/src/pages/MemberKYC.js new file mode 100644 index 0000000..dded191 --- /dev/null +++ b/src/pages/MemberKYC.js @@ -0,0 +1,142 @@ +import * as React from 'react'; +import Paper from '@mui/material/Paper'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; +import { Box, Typography, Button, TextField } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import SearchIcon from '@mui/icons-material/Search'; + +const columns = [ + { id: 'id', label: 'ID', minWidth: 50 }, + { id: 'createdDate', label: 'Created Date', minWidth: 100 }, + { + id: 'name', + label: 'Name', + minWidth: 100, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'description', + label: 'Description', + minWidth: 170, + align: 'right', + format: (value) => value.toLocaleString('en-US'), + }, + { + id: 'action', + label: 'Action', + minWidth: 170, + align: 'right', + format: (value) => value.toFixed(2), + }, +]; + +function createData(id, name, description, population, size) { + const today = new Date(); + return { id, name, description, population, size, createdDate: today.toString()}; +} + +const rows = [ + createData(1,'India', 'IN', 1324171354, 3287263), + createData(2,'China', 'CN', 1403500365, 9596961), + createData(3,'Italy', 'IT', 60483973, 301340), + createData(4,'United States', 'US', 327167434, 9833520), + createData(5,'Canada', 'CA', 37602103, 9984670), + createData(6,'Australia', 'AU', 25475400, 7692024), + createData(7,'Germany', 'DE', 83019200, 357578), + createData(8,'Ireland', 'IE', 4857000, 70273), + createData(9,'Mexico', 'MX', 126577691, 1972550), + createData(10,'Japan', 'JP', 126317000, 377973), + createData(11,'France', 'FR', 67022000, 640679), + createData(12,'United Kingdom', 'GB', 67545757, 242495), + createData(13,'Russia', 'RU', 146793744, 17098246), + createData(14,'Nigeria', 'NG', 200962417, 923768), + createData(15,'Brazil', 'BR', 210147125, 8515767), +]; + +export default function MemberKyc() { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + Manage Member KYC + + + + + + + + + + + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + {columns.map((column) => { + const value = row[column.id]; + return ( + + { + column.id === 'action' ? ( + + ) : value + } + + ); + })} + + ); + })} + +
+
+ +
+
+
+ ); +} diff --git a/src/pages/Register.js b/src/pages/Register.js new file mode 100644 index 0000000..c3c281b --- /dev/null +++ b/src/pages/Register.js @@ -0,0 +1,141 @@ +import React, { useState } from "react"; +import {Link} from 'react-router-dom'; +import { + TextField, + Button, + Box, + Typography, + Grid, + Paper, + InputAdornment, + IconButton, + FormControl, + InputLabel, + OutlinedInput, +} from "@mui/material"; +import Visibility from "@mui/icons-material/Visibility"; +import VisibilityOff from "@mui/icons-material/VisibilityOff"; + +const RegisterPage = () => { + // State for form fields + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + + // Handle password visibility toggle + const handleClickShowPassword = () => setShowPassword(!showPassword); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (password !== confirmPassword) { + alert("Passwords do not match!"); + return; + } + if (name && email && password && confirmPassword) { + // Handle registration logic, like calling an API to create the user + console.log("Registered with:", { name, email, password }); + } else { + alert("Please fill in all fields."); + } + }; + + return ( + + + + + Create an Account + +
+ + setName(e.target.value)} + required + /> + + + setEmail(e.target.value)} + type="email" + required + /> + + + + Password + setPassword(e.target.value)} + endAdornment={ + + + {showPassword ? : } + + + } + /> + + + + + Confirm Password + setConfirmPassword(e.target.value)} + endAdornment={ + + + {showPassword ? : } + + + } + /> + + + + + + +
+
+
+
+ ); +}; + +export default RegisterPage; \ No newline at end of file diff --git a/src/pages/Setting.js b/src/pages/Setting.js new file mode 100644 index 0000000..a7f49c5 --- /dev/null +++ b/src/pages/Setting.js @@ -0,0 +1,77 @@ +import React, { useState } from "react"; +import { + TextField, + Button, + Box, + Typography, + Paper, +} from "@mui/material"; + +const SettingPage = () => { + // State for form fields + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + + // Handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + if (name && email) { + // Handle registration logic, like calling an API to create the user + console.log("Registered with:", { name, email }); + } else { + alert("Please fill in all fields."); + } + }; + + return ( + + Manage Webservice + + + +
+ + setName(e.target.value)} + required + /> + + + setName(e.target.value)} + required + /> + + + setEmail(e.target.value)} + type="email" + required + /> + + + + + + +
+
+
+
+
+ ); +}; + +export default SettingPage; \ No newline at end of file diff --git a/src/routes/routes.js b/src/routes/routes.js new file mode 100644 index 0000000..20f6d38 --- /dev/null +++ b/src/routes/routes.js @@ -0,0 +1,95 @@ +import React from 'react'; +import { Routes, Route, useLocation, Navigate } from 'react-router-dom'; +import "../pages/Dashboard.css"; +import Sidebar from "../components/SideBar"; +import Header from "../components/Header"; +import { Box, Toolbar } from "@mui/material"; +// GENERAL +import Dasboard from '../pages/Dashboard'; +import LoginPage from '../pages/Login'; +import RegisterPage from '../pages/Register'; +// ADMIN +import ManageTransfers from '../pages/ManageTransfers'; +import ManageNotifications from '../pages/ManageNotifications'; +import ManageAccess from '../pages/ManageAccess'; +import ManageAccounts from '../pages/ManageAccount'; +import ManageGroups from '../pages/ManageGroups'; +import ManageMembers from '../pages/ManageMembers'; +import ManageMenus from '../pages/ManageMenu'; +import MemberKyc from '../pages/MemberKYC'; +import ManageCredential from '../pages/ManageCredential'; +import ManageCurrency from '../pages/ManageCurrency'; +import ManageWebservice from '../pages/ManageWebservice'; +import SettingPage from '../pages/Setting'; +// ESCROW +import TransactionHistory from '../escrowPages/TransactionHistory'; +import TransferPage from '../escrowPages/Transfer'; +import TicketConfirmationPage from '../escrowPages/TicketConfirmation'; + +// Mock Authentication Function +const isAuthenticated = () => { + return localStorage.getItem("authToken") !== null; +}; + +// Middleware Component for Protected Routes +const ProtectedRoute = ({ children }) => { + if (!isAuthenticated()) { + return ; + } + return children; +}; + +const Layout = ({ children }) => { + const location = useLocation(); + // Define routes where the Navbar should not appear + const hideNavbarRoutes = ['/login', "/register"]; + const shouldShowLayout = !hideNavbarRoutes.includes(location.pathname); + return ( + <> + {shouldShowLayout && + ( +
+ + + +
+ +
{children}
+ + +
+ ) + } + + ); +}; + +function App() { + return ( + + {/* GENERAL */} + } /> + } /> + } /> + {/* ADMIN */} + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + {/* ESCROW */} + } /> + } /> + } /> + + ); +} + +export default App; \ No newline at end of file diff --git a/src/style/Chart.css b/src/style/Chart.css new file mode 100644 index 0000000..68bc18e --- /dev/null +++ b/src/style/Chart.css @@ -0,0 +1,13 @@ +.chart { + margin: 20px 250px 0 270px; + background-color: #fff; + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + padding: 20px; +} + +.chart h3 { + margin-bottom: 20px; + color: #333; + font-size: 18px; +} \ No newline at end of file diff --git a/src/style/Header.css b/src/style/Header.css new file mode 100644 index 0000000..6dc574a --- /dev/null +++ b/src/style/Header.css @@ -0,0 +1,26 @@ +.header { + height: 60px; + background-color: #f5f5f5; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 20px; + margin-left: 250px; + border-bottom: 1px solid #ddd; +} + +.welcome h4 { + margin: 0; + font-size: 18px; + color: #333; +} + +.actions i { + margin-left: 20px; + font-size: 20px; + cursor: pointer; +} + +.actions i:hover { + color: #d32f2f; +} \ No newline at end of file diff --git a/src/style/MemberActivity.css b/src/style/MemberActivity.css new file mode 100644 index 0000000..dc686e0 --- /dev/null +++ b/src/style/MemberActivity.css @@ -0,0 +1,18 @@ +/* src/MyCharts.css */ +.charts-container { + display: flex; + justify-content: space-between; + gap: 20px; + flex-wrap: wrap; + padding: 20px; +} + +.chart-item { + width: 30%; + min-width: 250px; + text-align: center; +} + +.chart-item h3 { + margin-bottom: 10px; +} \ No newline at end of file diff --git a/src/style/SideBar.css b/src/style/SideBar.css new file mode 100644 index 0000000..ce2f73c --- /dev/null +++ b/src/style/SideBar.css @@ -0,0 +1,29 @@ +.sidebar { + width: 250px; + background-color: #d32f2f; + color: #fff; + height: 100vh; + position: fixed; + top: 0; + left: 0; + padding: 20px; +} + +.sidebar h2 { + font-size: 24px; + margin-bottom: 20px; +} + +.sidebar ul { + list-style-type: none; + padding: 0; +} + +.sidebar ul li { + margin: 15px 0; + cursor: pointer; +} + +.sidebar ul li:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/style/StatsCard.css b/src/style/StatsCard.css new file mode 100644 index 0000000..7ef93e2 --- /dev/null +++ b/src/style/StatsCard.css @@ -0,0 +1,35 @@ +.stats-card { + width: 200px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 8px; + padding: 15px; + text-align: center; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.stats-card h4 { + font-size: 16px; + color: #666; + margin: 0 0 10px; +} + +.stats-card h2 { + font-size: 28px; + margin: 0; + color: #333; +} + +.stats-card span { + font-size: 14px; + display: block; + margin-top: 10px; +} + +.stats-card span.positive { + color: green; +} + +.stats-card span.negative { + color: red; +} \ No newline at end of file diff --git a/src/style/TransactionList.css b/src/style/TransactionList.css new file mode 100644 index 0000000..f662875 --- /dev/null +++ b/src/style/TransactionList.css @@ -0,0 +1,38 @@ +.transaction-list { + background-color: #fff; + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + padding: 20px; + margin: 20px 250px 0 270px; +} + +.transaction-list h3 { + margin-bottom: 20px; + color: #333; + font-size: 18px; +} + +.transaction-list ul { + list-style-type: none; + padding: 0; +} + +.transaction-list li { + margin: 15px 0; + display: flex; + justify-content: space-between; + align-items: center; +} + +.progress { + width: 70%; + background-color: #eee; + height: 8px; + border-radius: 4px; + overflow: hidden; +} + +.progress-bar { + height: 8px; + background-color: #d32f2f; +} \ No newline at end of file