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 (
-
- );
-}
-
-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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+ );
+};
+
+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
+
+
+
+
+
+
+
+
+ );
+};
+
+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