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