add initial versions of components and services
This commit is contained in:
parent
3a78a71709
commit
43e5fde219
|
@ -1,23 +0,0 @@
|
||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/.pnp
|
|
||||||
.pnp.js
|
|
||||||
|
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
|
|
||||||
# production
|
|
||||||
/build
|
|
||||||
|
|
||||||
# misc
|
|
||||||
.DS_Store
|
|
||||||
.env.local
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
|
@ -12,9 +12,13 @@
|
||||||
"@testing-library/react": "^13.3.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
|
"bootstrap": "^5.1.3",
|
||||||
"react": "^18.1.0",
|
"react": "^18.1.0",
|
||||||
"react-dom": "^18.1.0",
|
"react-dom": "^18.1.0",
|
||||||
|
"react-router-dom": "^6.3.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
"react-validation": "^3.0.7",
|
||||||
|
"validator": "^13.7.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2982,6 +2986,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
|
||||||
|
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
|
||||||
|
"peer": true,
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/plugin-babel": {
|
"node_modules/@rollup/plugin-babel": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||||
|
@ -5061,6 +5075,18 @@
|
||||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||||
},
|
},
|
||||||
|
"node_modules/bootstrap": {
|
||||||
|
"version": "5.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
|
||||||
|
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/bootstrap"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@popperjs/core": "^2.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
@ -8197,6 +8223,14 @@
|
||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/history": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hoopy": {
|
"node_modules/hoopy": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||||
|
@ -11186,6 +11220,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.omit": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||||
|
},
|
||||||
"node_modules/lodash.sortby": {
|
"node_modules/lodash.sortby": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||||
|
@ -13631,6 +13670,30 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"history": "^5.2.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
|
||||||
|
"dependencies": {
|
||||||
|
"history": "^5.2.0",
|
||||||
|
"react-router": "6.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-scripts": {
|
"node_modules/react-scripts": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||||
|
@ -13703,6 +13766,40 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-validation": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-mxCD+1Z8hnNEtxR9QPYxP1bmpdMHyFen0gtH9urr2zt7fB9LADkpeehaoePJLU+0PO5e5JD3X4a2aMRSLz88cg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash.omit": "^4.5.0",
|
||||||
|
"prop-types": "^15.6.0",
|
||||||
|
"react": "^16.0.0",
|
||||||
|
"shallow-equal": "^1.0.0",
|
||||||
|
"uuid": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-validation/node_modules/react": {
|
||||||
|
"version": "16.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
|
||||||
|
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-validation/node_modules/uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||||
|
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
@ -14384,6 +14481,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/shallow-equal": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
@ -15469,6 +15571,14 @@
|
||||||
"node": ">=10.12.0"
|
"node": ">=10.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/validator": {
|
||||||
|
"version": "13.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
|
||||||
|
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
@ -18390,6 +18500,12 @@
|
||||||
"source-map": "^0.7.3"
|
"source-map": "^0.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.11.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
|
||||||
|
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"@rollup/plugin-babel": {
|
"@rollup/plugin-babel": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
|
||||||
|
@ -19956,6 +20072,12 @@
|
||||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||||
},
|
},
|
||||||
|
"bootstrap": {
|
||||||
|
"version": "5.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
|
||||||
|
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
@ -22211,6 +22333,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||||
},
|
},
|
||||||
|
"history": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hoopy": {
|
"hoopy": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
|
||||||
|
@ -24374,6 +24504,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||||
},
|
},
|
||||||
|
"lodash.omit": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||||
|
},
|
||||||
"lodash.sortby": {
|
"lodash.sortby": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||||
|
@ -25981,6 +26116,23 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||||
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
|
||||||
},
|
},
|
||||||
|
"react-router": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==",
|
||||||
|
"requires": {
|
||||||
|
"history": "^5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-router-dom": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==",
|
||||||
|
"requires": {
|
||||||
|
"history": "^5.2.0",
|
||||||
|
"react-router": "6.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||||
|
@ -26036,6 +26188,35 @@
|
||||||
"workbox-webpack-plugin": "^6.4.1"
|
"workbox-webpack-plugin": "^6.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-validation": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-mxCD+1Z8hnNEtxR9QPYxP1bmpdMHyFen0gtH9urr2zt7fB9LADkpeehaoePJLU+0PO5e5JD3X4a2aMRSLz88cg==",
|
||||||
|
"requires": {
|
||||||
|
"lodash.omit": "^4.5.0",
|
||||||
|
"prop-types": "^15.6.0",
|
||||||
|
"react": "^16.0.0",
|
||||||
|
"shallow-equal": "^1.0.0",
|
||||||
|
"uuid": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": {
|
||||||
|
"version": "16.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
|
||||||
|
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
@ -26533,6 +26714,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
},
|
},
|
||||||
|
"shallow-equal": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
||||||
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
@ -27345,6 +27531,11 @@
|
||||||
"source-map": "^0.7.3"
|
"source-map": "^0.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"validator": {
|
||||||
|
"version": "13.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
|
||||||
|
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw=="
|
||||||
|
},
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
"@testing-library/react": "^13.3.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
|
"bootstrap": "^5.1.3",
|
||||||
"react": "^18.1.0",
|
"react": "^18.1.0",
|
||||||
"react-dom": "^18.1.0",
|
"react-dom": "^18.1.0",
|
||||||
|
"react-router-dom": "^6.3.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4",
|
||||||
|
"react-validation": "^3.0.7",
|
||||||
|
"validator": "^13.7.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|
|
@ -1,45 +1,43 @@
|
||||||
import logo from './logo.svg';
|
import React, { Component } from "react";
|
||||||
import './App.css';
|
import { Routes, Route, Link } from "react-router-dom";
|
||||||
const axios = require('axios');
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import "./App.css";
|
||||||
|
import AuthService from "./services/auth.service";
|
||||||
|
import Login from "./components/login.component";
|
||||||
|
import Register from "./components/register.component";
|
||||||
|
import Home from "./components/home.component";
|
||||||
|
import Profile from "./components/profile.component";
|
||||||
|
|
||||||
function App() {
|
class App extends Component {
|
||||||
let results;
|
constructor(props) {
|
||||||
axios.get('http://0.0.0.0:8001/api/v1/search/?tag=tech&max_results=10')
|
super(props);
|
||||||
.then(function (response) {
|
this.logOut = this.logOut.bind(this);
|
||||||
// handle success
|
this.state = {
|
||||||
results = response.data.results;
|
showLessons: false,
|
||||||
|
currentUser: undefined,
|
||||||
})
|
};
|
||||||
.catch(function (error) {
|
}
|
||||||
// handle error
|
componentDidMount() {
|
||||||
console.log(error);
|
AuthService.login('cst@ctrl-c.club', 'PEACEandLOVE');
|
||||||
})
|
const user = AuthService.getCurrentUser();
|
||||||
.then(function () {
|
if (user) {
|
||||||
// always executed
|
this.setState({
|
||||||
|
currentUser: user,
|
||||||
|
showLessons: true,
|
||||||
});
|
});
|
||||||
return (
|
}
|
||||||
<div className="App">
|
}
|
||||||
<h1>Lessons Learned</h1>
|
logOut() {
|
||||||
|
AuthService.logout();
|
||||||
<table>
|
}
|
||||||
<tr>
|
render() {
|
||||||
<th>Title</th>
|
const { currentUser, showLessons } = this.state;
|
||||||
<th>Content</th>
|
console.log(currentUser,showLessons);
|
||||||
<th>Tags</th>
|
return (
|
||||||
</tr>
|
<div>
|
||||||
{results.map((val, key) => {
|
{currentUser}
|
||||||
return (
|
</div>
|
||||||
<tr key={key}>
|
);
|
||||||
<td>lesson title</td>
|
}
|
||||||
<td>{val.content}</td>
|
|
||||||
<td>{val.tags}</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import UserService from "../services/user.service";
|
||||||
|
export default class Home extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
content: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
componentDidMount() {
|
||||||
|
UserService.getPublicContent().then(
|
||||||
|
response => {
|
||||||
|
this.setState({
|
||||||
|
content: response.data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.setState({
|
||||||
|
content:
|
||||||
|
(error.response && error.response.data) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<header className="jumbotron">
|
||||||
|
<h3>{this.state.content}</h3>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import Form from "react-validation/build/form";
|
||||||
|
import Input from "react-validation/build/input";
|
||||||
|
import CheckButton from "react-validation/build/button";
|
||||||
|
import AuthService from "../services/auth.service";
|
||||||
|
const required = value => {
|
||||||
|
if (!value) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
This field is required!
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default class Login extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.handleLogin = this.handleLogin.bind(this);
|
||||||
|
this.onChangeUsername = this.onChangeUsername.bind(this);
|
||||||
|
this.onChangePassword = this.onChangePassword.bind(this);
|
||||||
|
this.state = {
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
loading: false,
|
||||||
|
message: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
onChangeUsername(e) {
|
||||||
|
this.setState({
|
||||||
|
username: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onChangePassword(e) {
|
||||||
|
this.setState({
|
||||||
|
password: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
handleLogin(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.setState({
|
||||||
|
message: "",
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
this.form.validateAll();
|
||||||
|
if (this.checkBtn.context._errors.length === 0) {
|
||||||
|
AuthService.login(this.state.username, this.state.password).then(
|
||||||
|
() => {
|
||||||
|
this.props.history.push("/profile");
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
const resMessage =
|
||||||
|
(error.response &&
|
||||||
|
error.response.data &&
|
||||||
|
error.response.data.message) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString();
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
message: resMessage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="card card-container">
|
||||||
|
<img
|
||||||
|
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
|
||||||
|
alt="profile-img"
|
||||||
|
className="profile-img-card"
|
||||||
|
/>
|
||||||
|
<Form
|
||||||
|
onSubmit={this.handleLogin}
|
||||||
|
ref={c => {
|
||||||
|
this.form = c;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="username">Username</label>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
name="username"
|
||||||
|
value={this.state.username}
|
||||||
|
onChange={this.onChangeUsername}
|
||||||
|
validations={[required]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="password">Password</label>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
className="form-control"
|
||||||
|
name="password"
|
||||||
|
value={this.state.password}
|
||||||
|
onChange={this.onChangePassword}
|
||||||
|
validations={[required]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<button
|
||||||
|
className="btn btn-primary btn-block"
|
||||||
|
disabled={this.state.loading}
|
||||||
|
>
|
||||||
|
{this.state.loading && (
|
||||||
|
<span className="spinner-border spinner-border-sm"></span>
|
||||||
|
)}
|
||||||
|
<span>Login</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{this.state.message && (
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
{this.state.message}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<CheckButton
|
||||||
|
style={{ display: "none" }}
|
||||||
|
ref={c => {
|
||||||
|
this.checkBtn = c;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import AuthService from "../services/auth.service";
|
||||||
|
|
||||||
|
export default class Profile extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
currentUser: AuthService.getCurrentUser()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { currentUser } = this.state;
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<header className="jumbotron">
|
||||||
|
<h3>
|
||||||
|
<strong>{currentUser.username}</strong> Profile
|
||||||
|
</h3>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
<strong>Token:</strong>{" "}
|
||||||
|
{currentUser.accessToken.substring(0, 20)} ...{" "}
|
||||||
|
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Id:</strong>{" "}
|
||||||
|
{currentUser.id}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Email:</strong>{" "}
|
||||||
|
{currentUser.email}
|
||||||
|
</p>
|
||||||
|
<strong>Authorities:</strong>
|
||||||
|
<ul>
|
||||||
|
{currentUser.roles &&
|
||||||
|
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import Form from "react-validation/build/form";
|
||||||
|
import Input from "react-validation/build/input";
|
||||||
|
import CheckButton from "react-validation/build/button";
|
||||||
|
import { isEmail } from "validator";
|
||||||
|
import AuthService from "../services/auth.service";
|
||||||
|
const required = value => {
|
||||||
|
if (!value) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
This field is required!
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const email = value => {
|
||||||
|
if (!isEmail(value)) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
This is not a valid email.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const vusername = value => {
|
||||||
|
if (value.length < 3 || value.length > 20) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
The username must be between 3 and 20 characters.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const vpassword = value => {
|
||||||
|
if (value.length < 6 || value.length > 40) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
The password must be between 6 and 40 characters.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default class Register extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.handleRegister = this.handleRegister.bind(this);
|
||||||
|
this.onChangeUsername = this.onChangeUsername.bind(this);
|
||||||
|
this.onChangeEmail = this.onChangeEmail.bind(this);
|
||||||
|
this.onChangePassword = this.onChangePassword.bind(this);
|
||||||
|
this.state = {
|
||||||
|
username: "",
|
||||||
|
email: "",
|
||||||
|
password: "",
|
||||||
|
successful: false,
|
||||||
|
message: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
onChangeUsername(e) {
|
||||||
|
this.setState({
|
||||||
|
username: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onChangeEmail(e) {
|
||||||
|
this.setState({
|
||||||
|
email: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onChangePassword(e) {
|
||||||
|
this.setState({
|
||||||
|
password: e.target.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
handleRegister(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.setState({
|
||||||
|
message: "",
|
||||||
|
successful: false
|
||||||
|
});
|
||||||
|
this.form.validateAll();
|
||||||
|
if (this.checkBtn.context._errors.length === 0) {
|
||||||
|
AuthService.register(
|
||||||
|
this.state.username,
|
||||||
|
this.state.email,
|
||||||
|
this.state.password
|
||||||
|
).then(
|
||||||
|
response => {
|
||||||
|
this.setState({
|
||||||
|
message: response.data.message,
|
||||||
|
successful: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
const resMessage =
|
||||||
|
(error.response &&
|
||||||
|
error.response.data &&
|
||||||
|
error.response.data.message) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString();
|
||||||
|
this.setState({
|
||||||
|
successful: false,
|
||||||
|
message: resMessage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="card card-container">
|
||||||
|
<img
|
||||||
|
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
|
||||||
|
alt="profile-img"
|
||||||
|
className="profile-img-card"
|
||||||
|
/>
|
||||||
|
<Form
|
||||||
|
onSubmit={this.handleRegister}
|
||||||
|
ref={c => {
|
||||||
|
this.form = c;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!this.state.successful && (
|
||||||
|
<div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="username">Username</label>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
name="username"
|
||||||
|
value={this.state.username}
|
||||||
|
onChange={this.onChangeUsername}
|
||||||
|
validations={[required, vusername]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="email">Email</label>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
name="email"
|
||||||
|
value={this.state.email}
|
||||||
|
onChange={this.onChangeEmail}
|
||||||
|
validations={[required, email]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="password">Password</label>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
className="form-control"
|
||||||
|
name="password"
|
||||||
|
value={this.state.password}
|
||||||
|
onChange={this.onChangePassword}
|
||||||
|
validations={[required, vpassword]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<button className="btn btn-primary btn-block">Sign Up</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{this.state.message && (
|
||||||
|
<div className="form-group">
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
this.state.successful
|
||||||
|
? "alert alert-success"
|
||||||
|
: "alert alert-danger"
|
||||||
|
}
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
{this.state.message}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<CheckButton
|
||||||
|
style={{ display: "none" }}
|
||||||
|
ref={c => {
|
||||||
|
this.checkBtn = c;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
export default function authHeader() {
|
||||||
|
const user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
if (user && user.accessToken) {
|
||||||
|
return { Authorization: 'bearer ' + user.accessToken };
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import axios from "axios";
|
||||||
|
const API_URL = "http://localhost:8001/api/v1/auth";
|
||||||
|
class AuthService {
|
||||||
|
login(username, password) {
|
||||||
|
|
||||||
|
let bodyFormData = new FormData();
|
||||||
|
|
||||||
|
bodyFormData.append('username', username);
|
||||||
|
bodyFormData.append('password', password);
|
||||||
|
|
||||||
|
return axios({
|
||||||
|
method: 'post',
|
||||||
|
url: API_URL + "/login",
|
||||||
|
headers: {'Content-Type' : 'multipart/form-data'},
|
||||||
|
data: bodyFormData})
|
||||||
|
.then(response => {
|
||||||
|
if (response.data) {
|
||||||
|
localStorage.setItem(
|
||||||
|
"username", username);
|
||||||
|
localStorage.setItem(
|
||||||
|
"token", response.data.access_token);
|
||||||
|
}
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
logout() {
|
||||||
|
localStorage.removeItem("user");
|
||||||
|
}
|
||||||
|
|
||||||
|
signup(username, email, password) {
|
||||||
|
return axios.post(API_URL + "/signup", {
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentUser() {
|
||||||
|
return localStorage.getItem('username');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new AuthService();
|
|
@ -0,0 +1,16 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
import authHeader from './auth-header';
|
||||||
|
const API_URL = 'http://localhost:8001/api/v1/lesson';
|
||||||
|
class UserService {
|
||||||
|
getLessons() {
|
||||||
|
return axios.get(
|
||||||
|
API_URL + '/',
|
||||||
|
{ headers: authHeader() });
|
||||||
|
}
|
||||||
|
|
||||||
|
getPublicContent(){
|
||||||
|
return {'hello-earthlings':'now take me to your leader'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new UserService();
|
|
@ -1,181 +0,0 @@
|
||||||
{
|
|
||||||
"name": "lessons_learned",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"react-validation": "^3.0.7",
|
|
||||||
"validator": "^13.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-tokens": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash.omit": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
|
||||||
},
|
|
||||||
"node_modules/loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"loose-envify": "cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object-assign": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/prop-types": {
|
|
||||||
"version": "15.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
|
||||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.4.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"react-is": "^16.13.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react": {
|
|
||||||
"version": "16.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
|
|
||||||
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.1.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"prop-types": "^15.6.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"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/react-validation": {
|
|
||||||
"version": "3.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
|
|
||||||
"integrity": "sha512-mxCD+1Z8hnNEtxR9QPYxP1bmpdMHyFen0gtH9urr2zt7fB9LADkpeehaoePJLU+0PO5e5JD3X4a2aMRSLz88cg==",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash.omit": "^4.5.0",
|
|
||||||
"prop-types": "^15.6.0",
|
|
||||||
"react": "^16.0.0",
|
|
||||||
"shallow-equal": "^1.0.0",
|
|
||||||
"uuid": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/shallow-equal": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
|
||||||
},
|
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "3.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
|
||||||
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/validator": {
|
|
||||||
"version": "13.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
|
|
||||||
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"js-tokens": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
|
||||||
},
|
|
||||||
"lodash.omit": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
|
||||||
},
|
|
||||||
"loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"requires": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"object-assign": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
|
||||||
},
|
|
||||||
"prop-types": {
|
|
||||||
"version": "15.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
|
||||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
|
||||||
"requires": {
|
|
||||||
"loose-envify": "^1.4.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"react-is": "^16.13.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react": {
|
|
||||||
"version": "16.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
|
|
||||||
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
|
|
||||||
"requires": {
|
|
||||||
"loose-envify": "^1.1.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"prop-types": "^15.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"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=="
|
|
||||||
},
|
|
||||||
"react-validation": {
|
|
||||||
"version": "3.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
|
|
||||||
"integrity": "sha512-mxCD+1Z8hnNEtxR9QPYxP1bmpdMHyFen0gtH9urr2zt7fB9LADkpeehaoePJLU+0PO5e5JD3X4a2aMRSLz88cg==",
|
|
||||||
"requires": {
|
|
||||||
"lodash.omit": "^4.5.0",
|
|
||||||
"prop-types": "^15.6.0",
|
|
||||||
"react": "^16.0.0",
|
|
||||||
"shallow-equal": "^1.0.0",
|
|
||||||
"uuid": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"shallow-equal": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
|
||||||
},
|
|
||||||
"uuid": {
|
|
||||||
"version": "3.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
|
||||||
},
|
|
||||||
"validator": {
|
|
||||||
"version": "13.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
|
|
||||||
"integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"react-validation": "^3.0.7",
|
|
||||||
"validator": "^13.7.0"
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue