diff --git a/frontend/components/App.js b/frontend/components/App.js
index 815684369..58520033f 100644
--- a/frontend/components/App.js
+++ b/frontend/components/App.js
@@ -1,9 +1,114 @@
import React from 'react'
+import axios from "axios"
+import TodoList from "./TodoList"
+import Form from "./Form"
const URL = 'http://localhost:9000/api/todos'
export default class App extends React.Component {
+ constructor(){
+ super();
+ this.state ={
+ todos: [],
+ error: {
+ message: "",
+ status: false
+ },
+ todoNameInput: ""
+ }
+ }
+
+
+ handleClearButton = () => {
+ this.setState({
+ ...this.state,
+ todos: this.state.todos.filter(element => {
+ return (element.completed === false)
+ })
+ })
+ }
+
+ toggleClick = (id) => {
+ axios.patch(`${URL}/${id}`)
+ .then(res => {
+ this.setState({
+ ...this.state, todos: this.state.todos.map(element => {
+ if (element.id !== id) return element
+ return res.data.data
+ })
+ })
+ })
+ .catch(this.setAxiosResponseError)
+ }
+
+
+
+ onChangeTodoInput = (event) => {
+ const { value } = event.target
+ this.setState({
+ ...this.state,
+ todoNameInput: value
+ })
+ }
+
+ setAxiosResponseError = err => this.setState({
+ ...this.state, error: {
+ message: err.response.data.message,
+ status: true
+ }
+ })
+
+ fetchAllTodos = () => {
+ axios.get(URL)
+ .then(res => {
+ this.setState({
+ ...this.state, todos: res.data.data, error: {}
+ })
+ })
+ .catch(this.setAxiosResponseError)
+ }
+
+ resetForm = () => {
+ this.setState({
+ ...this.state,
+ todoNameInput: ""
+ })
+ }
+
+ postNewTodo = () => {
+ axios.post(URL, {name: this.state.todoNameInput})
+ .then(res => {
+ this.setState({
+ ...this.state,
+ todos: this.state.todos.concat(res.data.data),
+ error: {
+ message: "",
+ status: false
+ }
+ })
+ this.resetForm();
+ })
+ .catch(this.setAxiosResponseError)
+ }
+
+ onSubmitTodo = (event) => {
+ event.preventDefault();
+ this.postNewTodo();
+ }
+
+ componentDidMount(){
+ this.fetchAllTodos();
+ }
+
render() {
- return null
+ const { todos } = this.state;
+ return (
+
+ {this.state.error.status?
Error: {this.state.error.message}
: <>>}
+
Todos:
+
+
+
+ )
}
}
diff --git a/frontend/components/Form.js b/frontend/components/Form.js
index 3932207be..57f5b2c35 100644
--- a/frontend/components/Form.js
+++ b/frontend/components/Form.js
@@ -1,7 +1,34 @@
import React from 'react'
export default class Form extends React.Component {
+
+ inputChangeHandler = (event) => {
+ this.props.onChangeTodoInput(event)
+ }
+
+ handleSubmit = (event) => {
+ this.props.onSubmitTodo(event);
+ }
+
+ handleClear = () => {
+ this.props.handleClearButton();
+ }
+
+
render() {
- return null
+ return (
+
+
+
+
+ )
}
}
diff --git a/frontend/components/Todo.js b/frontend/components/Todo.js
index aac687f6d..f1a464463 100644
--- a/frontend/components/Todo.js
+++ b/frontend/components/Todo.js
@@ -1,7 +1,14 @@
import React from 'react'
export default class Todo extends React.Component {
+
+ handleClick = () => {
+ this.props.toggleClick(this.props.data.id)
+ }
+
render() {
- return null
+ return (
+ {this.props.data.name}{this.props.data.completed? "✔" : ""}
+ )
}
}
diff --git a/frontend/components/TodoList.js b/frontend/components/TodoList.js
index ce08a27ba..6b2421b39 100644
--- a/frontend/components/TodoList.js
+++ b/frontend/components/TodoList.js
@@ -1,7 +1,15 @@
import React from 'react'
+import Todo from "./Todo"
export default class TodoList extends React.Component {
render() {
- return null
+
+ return (
+
+ {this.props.data.map(element => {
+ return()
+ })}
+
+ )
}
}
diff --git a/package-lock.json b/package-lock.json
index b00891377..3808af684 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12464,7 +12464,8 @@
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
},
"node_modules/read-pkg": {
"version": "6.0.0",
@@ -17895,8 +17896,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz",
"integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"@webpack-cli/info": {
"version": "1.4.1",
@@ -17911,8 +17911,7 @@
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz",
"integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"@xmldom/xmldom": {
"version": "0.7.5",
@@ -17981,15 +17980,13 @@
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"acorn-walk": {
"version": "7.2.0",
@@ -18061,8 +18058,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"ansi-align": {
"version": "3.0.1",
@@ -21079,8 +21075,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"ieee754": {
"version": "1.2.1",
@@ -22409,8 +22404,7 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"jest-regex-util": {
"version": "27.5.1",
@@ -24335,8 +24329,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
@@ -24622,7 +24615,8 @@
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
},
"read-pkg": {
"version": "6.0.0",
@@ -25588,8 +25582,7 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz",
"integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"styled-components": {
"version": "5.3.3",
@@ -26448,8 +26441,7 @@
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==",
- "dev": true,
- "requires": {}
+ "dev": true
}
}
},
@@ -26662,8 +26654,7 @@
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"xdg-basedir": {
"version": "4.0.0",