mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 05:32:18 +00:00
0.0.8
- Added Admin/Site config page in frontend for admin users - Added API POST/GET /config endpoint
This commit is contained in:
parent
8be4a190a6
commit
af02bd99cc
17 changed files with 826 additions and 24 deletions
474
web/package-lock.json
generated
474
web/package-lock.json
generated
|
@ -8,6 +8,7 @@
|
|||
"name": "goscrobble",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@reduxjs/toolkit": "^1.5.0",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
@ -15,6 +16,7 @@
|
|||
"axios": "^0.21.1",
|
||||
"bootstrap": "^4.6.0",
|
||||
"formik": "^2.2.6",
|
||||
"formik-material-ui": "^3.0.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^1.5.2",
|
||||
|
@ -2370,6 +2372,155 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/core": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz",
|
||||
"integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/styles": "^4.11.3",
|
||||
"@material-ui/system": "^4.11.3",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"@types/react-transition-group": "^4.2.0",
|
||||
"clsx": "^1.0.4",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"popper.js": "1.16.1-lts",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0 || ^17.0.0",
|
||||
"react-transition-group": "^4.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/material-ui"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.6 || ^17.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/core/node_modules/popper.js": {
|
||||
"version": "1.16.1-lts",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
|
||||
},
|
||||
"node_modules/@material-ui/styles": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz",
|
||||
"integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/hash": "^0.8.0",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"clsx": "^1.0.4",
|
||||
"csstype": "^2.5.2",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"jss": "^10.5.1",
|
||||
"jss-plugin-camel-case": "^10.5.1",
|
||||
"jss-plugin-default-unit": "^10.5.1",
|
||||
"jss-plugin-global": "^10.5.1",
|
||||
"jss-plugin-nested": "^10.5.1",
|
||||
"jss-plugin-props-sort": "^10.5.1",
|
||||
"jss-plugin-rule-value-function": "^10.5.1",
|
||||
"jss-plugin-vendor-prefixer": "^10.5.1",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/material-ui"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.6 || ^17.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/styles/node_modules/csstype": {
|
||||
"version": "2.6.16",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
|
||||
"integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
|
||||
},
|
||||
"node_modules/@material-ui/system": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
|
||||
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"csstype": "^2.5.2",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/material-ui"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.6 || ^17.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/system/node_modules/csstype": {
|
||||
"version": "2.6.16",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
|
||||
"integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
|
||||
},
|
||||
"node_modules/@material-ui/types": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
|
||||
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@material-ui/utils": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
|
||||
"integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0 || ^17.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
|
||||
|
@ -6186,6 +6337,15 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/css-vendor": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
|
||||
"integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.3",
|
||||
"is-in-browser": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/css-what": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
|
||||
|
@ -9009,6 +9169,17 @@
|
|||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/formik-material-ui": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/formik-material-ui/-/formik-material-ui-3.0.1.tgz",
|
||||
"integrity": "sha512-N8oxZIdhY70npRv86IfF6Zaaps9RL3a37XRdq02WDroB3XZC1mXs6lA/zQ09ZYFWYJp/UjI80SKVpVa/xJOJJA==",
|
||||
"peerDependencies": {
|
||||
"@material-ui/core": ">=4.0.0",
|
||||
"formik": ">=2.0.0",
|
||||
"react": ">=16.8.0",
|
||||
"tiny-warning": ">=1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/formik/node_modules/deepmerge": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
|
||||
|
@ -9954,6 +10125,11 @@
|
|||
"node": ">=8.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hyphenate-style-name": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
@ -10115,6 +10291,14 @@
|
|||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/indefinite-observable": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz",
|
||||
"integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==",
|
||||
"dependencies": {
|
||||
"symbol-observable": "1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
|
@ -10432,6 +10616,11 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-in-browser": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
|
||||
"integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
|
@ -12845,6 +13034,89 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz",
|
||||
"integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"csstype": "^3.0.2",
|
||||
"indefinite-observable": "^2.0.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/jss"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-camel-case": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz",
|
||||
"integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"hyphenate-style-name": "^1.0.3",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-default-unit": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz",
|
||||
"integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-global": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz",
|
||||
"integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-nested": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz",
|
||||
"integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-props-sort": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz",
|
||||
"integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-rule-value-function": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz",
|
||||
"integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/jss-plugin-vendor-prefixer": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz",
|
||||
"integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"css-vendor": "^2.0.8",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
|
||||
|
@ -24050,6 +24322,96 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/core": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz",
|
||||
"integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/styles": "^4.11.3",
|
||||
"@material-ui/system": "^4.11.3",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"@types/react-transition-group": "^4.2.0",
|
||||
"clsx": "^1.0.4",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"popper.js": "1.16.1-lts",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0 || ^17.0.0",
|
||||
"react-transition-group": "^4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"popper.js": {
|
||||
"version": "1.16.1-lts",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
|
||||
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/styles": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz",
|
||||
"integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@emotion/hash": "^0.8.0",
|
||||
"@material-ui/types": "^5.1.0",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"clsx": "^1.0.4",
|
||||
"csstype": "^2.5.2",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"jss": "^10.5.1",
|
||||
"jss-plugin-camel-case": "^10.5.1",
|
||||
"jss-plugin-default-unit": "^10.5.1",
|
||||
"jss-plugin-global": "^10.5.1",
|
||||
"jss-plugin-nested": "^10.5.1",
|
||||
"jss-plugin-props-sort": "^10.5.1",
|
||||
"jss-plugin-rule-value-function": "^10.5.1",
|
||||
"jss-plugin-vendor-prefixer": "^10.5.1",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"csstype": {
|
||||
"version": "2.6.16",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
|
||||
"integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/system": {
|
||||
"version": "4.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
|
||||
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@material-ui/utils": "^4.11.2",
|
||||
"csstype": "^2.5.2",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"csstype": {
|
||||
"version": "2.6.16",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
|
||||
"integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@material-ui/types": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
|
||||
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
|
||||
"requires": {}
|
||||
},
|
||||
"@material-ui/utils": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
|
||||
"integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
|
||||
|
@ -27073,6 +27435,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"css-vendor": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
|
||||
"integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.8.3",
|
||||
"is-in-browser": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
|
||||
|
@ -29281,6 +29652,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"formik-material-ui": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/formik-material-ui/-/formik-material-ui-3.0.1.tgz",
|
||||
"integrity": "sha512-N8oxZIdhY70npRv86IfF6Zaaps9RL3a37XRdq02WDroB3XZC1mXs6lA/zQ09ZYFWYJp/UjI80SKVpVa/xJOJJA==",
|
||||
"requires": {}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
|
@ -30045,6 +30422,11 @@
|
|||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
|
||||
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
|
||||
},
|
||||
"hyphenate-style-name": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
@ -30152,6 +30534,14 @@
|
|||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
|
||||
},
|
||||
"indefinite-observable": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz",
|
||||
"integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==",
|
||||
"requires": {
|
||||
"symbol-observable": "1.2.0"
|
||||
}
|
||||
},
|
||||
"indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
|
@ -30379,6 +30769,11 @@
|
|||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-in-browser": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
|
||||
"integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
|
||||
},
|
||||
"is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
|
@ -32151,6 +32546,85 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jss": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz",
|
||||
"integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"csstype": "^3.0.2",
|
||||
"indefinite-observable": "^2.0.1",
|
||||
"is-in-browser": "^1.1.3",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-camel-case": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz",
|
||||
"integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"hyphenate-style-name": "^1.0.3",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-default-unit": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz",
|
||||
"integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-global": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz",
|
||||
"integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-nested": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz",
|
||||
"integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-props-sort": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz",
|
||||
"integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"jss-plugin-rule-value-function": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz",
|
||||
"integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"jss": "10.6.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"jss-plugin-vendor-prefixer": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz",
|
||||
"integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"css-vendor": "^2.0.8",
|
||||
"jss": "10.6.0"
|
||||
}
|
||||
},
|
||||
"jsx-ast-utils": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@reduxjs/toolkit": "^1.5.0",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
@ -10,6 +11,7 @@
|
|||
"axios": "^0.21.1",
|
||||
"bootstrap": "^4.6.0",
|
||||
"formik": "^2.2.6",
|
||||
"formik-material-ui": "^3.0.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"react": "^17.0.2",
|
||||
"react-bootstrap": "^1.5.2",
|
||||
|
|
|
@ -25,6 +25,7 @@ export const PostLogin = (formValues) => {
|
|||
uuid: expandedUser.sub,
|
||||
exp: expandedUser.exp,
|
||||
username: expandedUser.username,
|
||||
admin: expandedUser.admin
|
||||
}
|
||||
|
||||
toast.success('Successfully logged in.');
|
||||
|
@ -72,3 +73,31 @@ export const getRecentScrobbles = (id) => {
|
|||
return data.data;
|
||||
});
|
||||
};
|
||||
|
||||
export const getConfigs = () => {
|
||||
return axios.get(process.env.REACT_APP_API_URL + "config", { headers: getHeaders() })
|
||||
.then((data) => {
|
||||
return data.data;
|
||||
});
|
||||
};
|
||||
|
||||
export const postConfigs = (values, toggle) => {
|
||||
if (toggle) {
|
||||
values.REGISTRATION_ENABLED = "1"
|
||||
} else {
|
||||
values.REGISTRATION_ENABLED = "0"
|
||||
}
|
||||
|
||||
return axios.post(process.env.REACT_APP_API_URL + "config", values, { headers: getHeaders() })
|
||||
.then((data) => {
|
||||
if (data.data && data.data.message) {
|
||||
toast.success(data.data.message);
|
||||
} else if (data.data && data.data.error) {
|
||||
toast.error(data.data.error);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error('Error updating values');
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import './App.css';
|
||||
import { Route, Switch, withRouter } from 'react-router-dom';
|
||||
|
||||
import Home from './Pages/Home';
|
||||
import About from './Pages/About';
|
||||
|
||||
import Dashboard from './Pages/Dashboard';
|
||||
import Profile from './Pages/Profile';
|
||||
import Admin from './Pages/Admin';
|
||||
import Login from './Pages/Login';
|
||||
import Settings from './Pages/Settings';
|
||||
import Register from './Pages/Register';
|
||||
|
||||
import Navigation from './Components/Navigation';
|
||||
|
||||
import { Route, Switch, withRouter } from 'react-router-dom';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import './App.css';
|
||||
|
||||
const App = () => {
|
||||
let boolTrue = true
|
||||
|
@ -24,7 +25,8 @@ const App = () => {
|
|||
|
||||
<Route path="/dashboard" component={Dashboard} />
|
||||
<Route path="/profile" component={Profile} />
|
||||
<Route path="/settings" component={Settings} />
|
||||
|
||||
<Route path="/admin" component={Admin} />
|
||||
|
||||
<Route path="/login" component={Login} />
|
||||
<Route path="/register" component={Register} />
|
||||
|
|
|
@ -33,10 +33,14 @@ const Navigation = () => {
|
|||
let { user, Logout } = useContext(AuthContext);
|
||||
let [collapsed, setCollapsed] = useState(true);
|
||||
|
||||
const toggleCollapsed = () => {
|
||||
setCollapsed(!collapsed)
|
||||
}
|
||||
|
||||
const renderMobileNav = () => {
|
||||
return <Navbar color="dark" dark fixed="top">
|
||||
<NavbarBrand className="mr-auto"><img src={logo} className="nav-logo" alt="logo" /> GoScrobble</NavbarBrand>
|
||||
<NavbarToggler onClick={setCollapsed(!collapsed)} className="mr-2" />
|
||||
<NavbarToggler onClick={toggleCollapsed} className="mr-2" />
|
||||
<Collapse isOpen={!collapsed} navbar>
|
||||
{user ?
|
||||
<Nav className="navLinkLoginMobile" navbar>
|
||||
|
@ -55,6 +59,12 @@ const Navigation = () => {
|
|||
style={active === "profile" ? activeStyle : {}}
|
||||
className="navLinkMobile"
|
||||
>Profile</Link>
|
||||
{user.admin &&
|
||||
<Link
|
||||
to="/admin"
|
||||
style={active === "admin" ? activeStyle : {}}
|
||||
className="navLink"
|
||||
>Admin</Link>}
|
||||
<Link to="/" className="navLink" onClick={Logout}>Logout</Link>
|
||||
</Nav>
|
||||
: <Nav className="navLinkLoginMobile" navbar>
|
||||
|
@ -126,7 +136,13 @@ const Navigation = () => {
|
|||
style={active === "profile" ? activeStyle : {}}
|
||||
className="navLink"
|
||||
>{user.username}</Link>
|
||||
<Link to="/" className="navLink" onClick={Logout}>Logout</Link>
|
||||
{user.admin &&
|
||||
<Link
|
||||
to="/admin"
|
||||
style={active === "admin" ? activeStyle : {}}
|
||||
className="navLink"
|
||||
>Admin</Link>}
|
||||
<Link to="/admin" className="navLink" onClick={Logout}>Logout</Link>
|
||||
</div>
|
||||
:
|
||||
<div className="navLinkLogin">
|
||||
|
|
15
web/src/Pages/Admin.css
Normal file
15
web/src/Pages/Admin.css
Normal file
|
@ -0,0 +1,15 @@
|
|||
.adminBody {
|
||||
padding: 20px 5px 5px 5px;
|
||||
font-size: 16pt;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.adminFields {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.admin {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
margin-top:-5px;
|
||||
}
|
107
web/src/Pages/Admin.js
Normal file
107
web/src/Pages/Admin.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
import React, { useContext, useState, useEffect } from 'react';
|
||||
import '../App.css';
|
||||
import './Login.css';
|
||||
import { Button } from 'reactstrap';
|
||||
import { Formik, Form, Field } from 'formik';
|
||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||
import AuthContext from '../Contexts/AuthContext';
|
||||
import { Switch } from 'formik-material-ui';
|
||||
import { getConfigs, postConfigs } from '../Api/index'
|
||||
|
||||
const Admin = () => {
|
||||
const { user } = useContext(AuthContext);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [configs, setConfigs] = useState({})
|
||||
const [toggle, setToggle] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
getConfigs()
|
||||
.then(data => {
|
||||
setConfigs(data.configs);
|
||||
setToggle(data.configs.REGISTRATION_ENABLED === "1")
|
||||
setLoading(false);
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (!user || !user.admin) {
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>Unauthorized</h1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<ScaleLoader color="#6AD7E5" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const handleToggle = () => {
|
||||
setToggle(!toggle);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pageWrapper">
|
||||
<h1>
|
||||
Admin Panel
|
||||
</h1>
|
||||
<div className="loginBody">
|
||||
<Formik
|
||||
initialValues={configs}
|
||||
onSubmit={(values) => postConfigs(values, toggle)}
|
||||
>
|
||||
<Form><br/>
|
||||
<label>
|
||||
<Field
|
||||
type="checkbox"
|
||||
name="REGISTRATION_ENABLED"
|
||||
onChange={handleToggle}
|
||||
component={Switch}
|
||||
checked={toggle}
|
||||
value={toggle}
|
||||
/>
|
||||
Registration Enabled
|
||||
</label><br/><br/>
|
||||
<label>
|
||||
LastFM Api Key<br/>
|
||||
<Field
|
||||
name="LASTFM_API_KEY"
|
||||
type="text"
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
<label>
|
||||
Spotify App ID<br/>
|
||||
<Field
|
||||
name="SPOTIFY_APP_ID"
|
||||
type="text"
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Spotify App Secret<br/>
|
||||
<Field
|
||||
name="SPOTIFY_APP_SECRET"
|
||||
type="text"
|
||||
className="loginFields"
|
||||
/>
|
||||
</label>
|
||||
<br/><br/>
|
||||
<Button
|
||||
color="primary"
|
||||
type="submit"
|
||||
className="loginButton"
|
||||
disabled={loading}
|
||||
>Update</Button>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Admin;
|
|
@ -10,7 +10,7 @@ import AuthContext from '../Contexts/AuthContext';
|
|||
const Dashboard = () => {
|
||||
const history = useHistory();
|
||||
let { user } = useContext(AuthContext);
|
||||
let [isLoading, setIsLoading] = useState(true);
|
||||
let [loading, setLoading] = useState(true);
|
||||
let [dashboardData, setDashboardData] = useState({});
|
||||
|
||||
if (!user) {
|
||||
|
@ -24,7 +24,7 @@ const Dashboard = () => {
|
|||
getRecentScrobbles(user.uuid)
|
||||
.then(data => {
|
||||
setDashboardData(data);
|
||||
setIsLoading(false);
|
||||
setLoading(false);
|
||||
})
|
||||
}, [user])
|
||||
|
||||
|
@ -33,8 +33,8 @@ const Dashboard = () => {
|
|||
<h1>
|
||||
Dashboard!
|
||||
</h1>
|
||||
{isLoading
|
||||
? <ScaleLoader color="#FFF" size={60} />
|
||||
{loading
|
||||
? <ScaleLoader color="#6AD7E5" size={60} />
|
||||
: <ScrobbleTable data={dashboardData} />
|
||||
}
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue