diff --git a/frontend_react/.gitignore b/frontend_react/.gitignore
deleted file mode 100644
index 4d29575..0000000
--- a/frontend_react/.gitignore
+++ /dev/null
@@ -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*
diff --git a/frontend_react/package-lock.json b/frontend_react/package-lock.json
index a3e6ebf..ee0ac6e 100644
--- a/frontend_react/package-lock.json
+++ b/frontend_react/package-lock.json
@@ -12,9 +12,13 @@
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
+ "bootstrap": "^5.1.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
+ "react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
+ "react-validation": "^3.0.7",
+ "validator": "^13.7.0",
"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": {
"version": "5.3.1",
"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",
"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": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -8197,6 +8223,14 @@
"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": {
"version": "0.1.4",
"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",
"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": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -13631,6 +13670,30 @@
"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": {
"version": "5.0.1",
"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": {
"version": "3.6.0",
"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",
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -15469,6 +15571,14 @@
"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": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -18390,6 +18500,12 @@
"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": {
"version": "5.3.1",
"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",
"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": {
"version": "1.1.11",
"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",
"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": {
"version": "0.1.4",
"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",
"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": {
"version": "4.7.0",
"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",
"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": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
@@ -26036,6 +26188,35 @@
"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": {
"version": "3.6.0",
"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",
"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": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -27345,6 +27531,11 @@
"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": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/frontend_react/package.json b/frontend_react/package.json
index 5ce05d2..ad54f5e 100644
--- a/frontend_react/package.json
+++ b/frontend_react/package.json
@@ -7,10 +7,14 @@
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
+ "bootstrap": "^5.1.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
+ "react-router-dom": "^6.3.0",
"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": {
"start": "react-scripts start",
diff --git a/frontend_react/src/App.js b/frontend_react/src/App.js
index 9986dfa..59e1332 100644
--- a/frontend_react/src/App.js
+++ b/frontend_react/src/App.js
@@ -1,45 +1,43 @@
-import logo from './logo.svg';
-import './App.css';
-const axios = require('axios');
+import React, { Component } from "react";
+import { Routes, Route, Link } from "react-router-dom";
+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() {
- let results;
- axios.get('http://0.0.0.0:8001/api/v1/search/?tag=tech&max_results=10')
- .then(function (response) {
- // handle success
- results = response.data.results;
-
- })
- .catch(function (error) {
- // handle error
- console.log(error);
- })
- .then(function () {
- // always executed
+class App extends Component {
+ constructor(props) {
+ super(props);
+ this.logOut = this.logOut.bind(this);
+ this.state = {
+ showLessons: false,
+ currentUser: undefined,
+ };
+ }
+ componentDidMount() {
+ AuthService.login('cst@ctrl-c.club', 'PEACEandLOVE');
+ const user = AuthService.getCurrentUser();
+ if (user) {
+ this.setState({
+ currentUser: user,
+ showLessons: true,
});
- return (
-
-
Lessons Learned
-
-
-
- Title |
- Content |
- Tags |
-
- {results.map((val, key) => {
- return (
-
- lesson title |
- {val.content} |
- {val.tags} |
-
- )
- })}
-
-
-
- );
+ }
+ }
+ logOut() {
+ AuthService.logout();
+ }
+ render() {
+ const { currentUser, showLessons } = this.state;
+ console.log(currentUser,showLessons);
+ return (
+
+ {currentUser}
+
+ );
+ }
}
-
export default App;
diff --git a/frontend_react/src/components/home.component.js b/frontend_react/src/components/home.component.js
new file mode 100644
index 0000000..b114b52
--- /dev/null
+++ b/frontend_react/src/components/home.component.js
@@ -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 (
+
+
+
+ );
+ }
+}
diff --git a/frontend_react/src/components/login.component.js b/frontend_react/src/components/login.component.js
new file mode 100644
index 0000000..ed53520
--- /dev/null
+++ b/frontend_react/src/components/login.component.js
@@ -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 (
+
+ This field is required!
+
+ );
+ }
+};
+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 (
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/frontend_react/src/components/profile.component.js b/frontend_react/src/components/profile.component.js
new file mode 100644
index 0000000..41b137a
--- /dev/null
+++ b/frontend_react/src/components/profile.component.js
@@ -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 (
+
+
+
+ {currentUser.username} Profile
+
+
+
+ Token:{" "}
+ {currentUser.accessToken.substring(0, 20)} ...{" "}
+ {currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
+
+
+ Id:{" "}
+ {currentUser.id}
+
+
+ Email:{" "}
+ {currentUser.email}
+
+
Authorities:
+
+ {currentUser.roles &&
+ currentUser.roles.map((role, index) => - {role}
)}
+
+
+ );
+ }
+}
diff --git a/frontend_react/src/components/register.component.js b/frontend_react/src/components/register.component.js
new file mode 100644
index 0000000..07c13e1
--- /dev/null
+++ b/frontend_react/src/components/register.component.js
@@ -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 (
+
+ This field is required!
+
+ );
+ }
+};
+const email = value => {
+ if (!isEmail(value)) {
+ return (
+
+ This is not a valid email.
+
+ );
+ }
+};
+const vusername = value => {
+ if (value.length < 3 || value.length > 20) {
+ return (
+
+ The username must be between 3 and 20 characters.
+
+ );
+ }
+};
+const vpassword = value => {
+ if (value.length < 6 || value.length > 40) {
+ return (
+
+ The password must be between 6 and 40 characters.
+
+ );
+ }
+};
+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 (
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/frontend_react/src/services/auth-header.js b/frontend_react/src/services/auth-header.js
new file mode 100644
index 0000000..5b044a9
--- /dev/null
+++ b/frontend_react/src/services/auth-header.js
@@ -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 {};
+ }
+ }
+
\ No newline at end of file
diff --git a/frontend_react/src/services/auth.service.js b/frontend_react/src/services/auth.service.js
new file mode 100644
index 0000000..fb5e826
--- /dev/null
+++ b/frontend_react/src/services/auth.service.js
@@ -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();
diff --git a/frontend_react/src/services/user.service.js b/frontend_react/src/services/user.service.js
new file mode 100644
index 0000000..cf52ea9
--- /dev/null
+++ b/frontend_react/src/services/user.service.js
@@ -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();
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 66144af..0000000
--- a/package-lock.json
+++ /dev/null
@@ -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=="
- }
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index ed25423..0000000
--- a/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "react-validation": "^3.0.7",
- "validator": "^13.7.0"
- }
-}