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 0000000..5f2edf3 Binary files /dev/null and b/src/logo/Logo.jpeg differ 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