Update: components
This commit is contained in:
parent
89418c2757
commit
d3ed639939
9 changed files with 309 additions and 78 deletions
76
todo-app/package-lock.json
generated
76
todo-app/package-lock.json
generated
|
|
@ -799,6 +799,15 @@
|
|||
"resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
|
||||
"integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw=="
|
||||
},
|
||||
"@semantic-ui-react/event-stack": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@semantic-ui-react/event-stack/-/event-stack-3.0.0.tgz",
|
||||
"integrity": "sha512-5qVx0KdwN1iBWrbiXiuuaw1NShhmveNiEHynq/sjvI6U9eXn/k3yMZRZgeQof45iVwDP5NDy/fsF1sDcsk4eNA==",
|
||||
"requires": {
|
||||
"exenv": "^1.2.2",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@svgr/core": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-2.4.1.tgz",
|
||||
|
|
@ -2600,6 +2609,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||
|
|
@ -4240,6 +4254,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"exenv": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||
|
|
@ -4598,6 +4617,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"font-awesome": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
|
||||
"integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
|
|
@ -7129,6 +7153,11 @@
|
|||
"topo": "2.x.x"
|
||||
}
|
||||
},
|
||||
"jquery": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
|
||||
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
|
||||
},
|
||||
"js-levenshtein": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz",
|
||||
|
|
@ -7266,6 +7295,11 @@
|
|||
"array-includes": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"keyboard-key": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/keyboard-key/-/keyboard-key-1.0.2.tgz",
|
||||
"integrity": "sha512-05cjQmw4ss/YuY2utmVim0wywDyBZGUivo8siLPkWinwGWtKlO8/4RGbPUqNycwlD3u/3D15eNRjnNAyaTDs8g=="
|
||||
},
|
||||
"killable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
||||
|
|
@ -12411,6 +12445,43 @@
|
|||
"node-forge": "0.7.5"
|
||||
}
|
||||
},
|
||||
"semantic-ui-css": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz",
|
||||
"integrity": "sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg==",
|
||||
"requires": {
|
||||
"jquery": "x.*"
|
||||
}
|
||||
},
|
||||
"semantic-ui-react": {
|
||||
"version": "0.83.0",
|
||||
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-0.83.0.tgz",
|
||||
"integrity": "sha512-rPW4TZwbDJRJZeKxCpYuNiRnBwUpWeDkZ/yF3j5iLNS8hZ6yOjoFFmqGohqpqKD+jVyzlxz2NCmah54mwbNGOw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@semantic-ui-react/event-stack": "^3.0.0",
|
||||
"classnames": "^2.2.6",
|
||||
"keyboard-key": "^1.0.2",
|
||||
"lodash": "^4.17.10",
|
||||
"prop-types": "^15.6.2",
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.1.2.tgz",
|
||||
"integrity": "sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.12.0"
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
|
||||
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
|
|
@ -12562,6 +12633,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"shallowequal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
"dependencies": {
|
||||
"ajv": "^6.5.4",
|
||||
"axios": "^0.18.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"immutability-helper": "^2.8.1",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-scripts": "2.0.4",
|
||||
"redux": "^4.0.1",
|
||||
"redux-thunk": "^2.3.0"
|
||||
"redux-thunk": "^2.3.0",
|
||||
"semantic-ui-css": "^2.4.1",
|
||||
"semantic-ui-react": "^0.83.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
import React, { Component } from 'react';
|
||||
import './App.css';
|
||||
// import TodosContainer from './containers/TodosContainer.old'
|
||||
import TodosContainer from './containers/TodosContainer'
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="header">
|
||||
<h1>Todo List</h1>
|
||||
</div>
|
||||
<TodosContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<TodosContainer />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
30
todo-app/src/components/InputBox.js
Normal file
30
todo-app/src/components/InputBox.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import React, { Component } from 'react'
|
||||
|
||||
class InputBox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
createTodo = (e) => {
|
||||
if (e.key === 'Enter' && !(this.getTitle.value === '')) {
|
||||
this.props.createTodo(this.getTitle.value)
|
||||
this.getTitle.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return(
|
||||
<div>
|
||||
<div className="header">
|
||||
<h1>Todo List</h1>
|
||||
</div>
|
||||
<div className="inputContainer">
|
||||
<input className="taskInput" type="text" placeholder="Add a task" maxLength="50"
|
||||
onKeyPress={this.createTodo} ref={(input)=>this.getTitle = input} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default InputBox;
|
||||
31
todo-app/src/components/TodoItem.js
Normal file
31
todo-app/src/components/TodoItem.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import React, { Component } from 'react'
|
||||
|
||||
class TodoItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
updateTodo = (e, id) => {
|
||||
this.props.updateTodo({id: id, checked: e.target.checked})
|
||||
}
|
||||
|
||||
deleteTodo = (id) => {
|
||||
this.props.deleteTodo(id)
|
||||
}
|
||||
|
||||
render() {
|
||||
const todo = this.props.todo;
|
||||
return(
|
||||
<li className="task" key={todo.id} id={todo.id}>
|
||||
<input className="taskCheckbox" type="checkbox"
|
||||
checked={todo.done} onChange={(e) => this.updateTodo(e, todo.id)} />
|
||||
<label className="taskLabel">{todo.title}</label>
|
||||
<span className="deleteTaskBtn" onClick={(e) => this.deleteTodo(todo.id)}>
|
||||
x
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TodoItem;
|
||||
27
todo-app/src/components/TodoList.js
Normal file
27
todo-app/src/components/TodoList.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import React, { Component } from 'react'
|
||||
import TodoItem from './TodoItem'
|
||||
|
||||
class TodoList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const todos = this.props.todos;
|
||||
return(
|
||||
<div className="listWrapper">
|
||||
<ul className="taskList">
|
||||
{todos.map((todo) => {
|
||||
return (
|
||||
<TodoItem todo={todo} key={todo.id} id={todo.id}
|
||||
updateTodo={this.props.updateTodo}
|
||||
deleteTodo={this.props.deleteTodo} />
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TodoList;
|
||||
|
|
@ -2,80 +2,65 @@ import React, { Component } from 'react'
|
|||
import axios from 'axios'
|
||||
import { connect } from 'react-redux'
|
||||
import { loadTodos, addTodo, toggleTodo, deleteTodo } from '../actions/actionCreators'
|
||||
import InputBox from '../components/InputBox'
|
||||
import TodoList from '../components/TodoList'
|
||||
|
||||
class TodosContainer extends Component {
|
||||
class Todos extends Component {
|
||||
|
||||
getTodos() {
|
||||
axios.get('/api/v1/todos')
|
||||
.then(response => {
|
||||
this.props.dispatch(loadTodos(response.data));
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
createTodo = (e) => {
|
||||
if (e.key === 'Enter' && !(this.getTitle.value === '')) {
|
||||
axios.post('/api/v1/todos', {todo: {title: this.getTitle.value}})
|
||||
.then(response => {
|
||||
this.props.dispatch(addTodo(response.data.id, response.data.title))
|
||||
this.getTitle.value = '';
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
|
||||
updateTodo = (e, id) => {
|
||||
axios.put(`/api/v1/todos/${id}`, {todo: {done: e.target.checked}})
|
||||
.then(response => {
|
||||
this.props.dispatch(toggleTodo(id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
deleteTodo = (id) => {
|
||||
axios.delete(`/api/v1/todos/${id}`)
|
||||
.then(response => {
|
||||
this.props.dispatch(deleteTodo(id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getTodos();
|
||||
getTodos() {
|
||||
axios.get('/api/v1/todos')
|
||||
.then(response => {
|
||||
this.props.dispatch(loadTodos(response.data));
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
createTodo = (title) => {
|
||||
if (!(title === '')) {
|
||||
axios.post('/api/v1/todos', {todo: {title: title}})
|
||||
.then(response => {
|
||||
this.props.dispatch(addTodo(response.data.id, response.data.title))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
|
||||
updateTodo = (params) => {
|
||||
axios.put(`/api/v1/todos/${params.id}`, {todo: {done: params.checked}})
|
||||
.then(response => {
|
||||
this.props.dispatch(toggleTodo(params.id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
deleteTodo = (id) => {
|
||||
axios.delete(`/api/v1/todos/${id}`)
|
||||
.then(response => {
|
||||
this.props.dispatch(deleteTodo(id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getTodos();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className="inputContainer">
|
||||
<input className="taskInput" type="text" placeholder="Add a task" maxLength="50"
|
||||
onKeyPress={this.createTodo} ref={(input)=>this.getTitle = input} />
|
||||
</div>
|
||||
<div className="listWrapper">
|
||||
<ul className="taskList">
|
||||
{this.props.todos.map((todo) => {
|
||||
return(
|
||||
<li className="task" key={todo.id} id={todo.id}>
|
||||
<input className="taskCheckbox" type="checkbox"
|
||||
checked={todo.done} onChange={(e) => this.updateTodo(e, todo.id)} />
|
||||
<label className="taskLabel">{todo.title}</label>
|
||||
<span className="deleteTaskBtn" onClick={(e) => this.deleteTodo(todo.id)}>
|
||||
x
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<div className="container">
|
||||
<InputBox createTodo={this.createTodo} />
|
||||
<TodoList todos={this.props.todos}
|
||||
updateTodo={this.updateTodo}
|
||||
deleteTodo={this.deleteTodo} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
todos: state.todos
|
||||
}
|
||||
return {
|
||||
todos: state.todos
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TodosContainer)
|
||||
export default connect(mapStateToProps)(Todos)
|
||||
|
|
|
|||
84
todo-app/src/containers/TodosContainer.old.js
Normal file
84
todo-app/src/containers/TodosContainer.old.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import React, { Component } from 'react'
|
||||
import axios from 'axios'
|
||||
import { connect } from 'react-redux'
|
||||
import { loadTodos, addTodo, toggleTodo, deleteTodo } from '../actions/actionCreators'
|
||||
|
||||
class TodosContainer extends Component {
|
||||
|
||||
getTodos() {
|
||||
axios.get('/api/v1/todos')
|
||||
.then(response => {
|
||||
this.props.dispatch(loadTodos(response.data));
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
createTodo = (e) => {
|
||||
if (e.key === 'Enter' && !(this.getTitle.value === '')) {
|
||||
axios.post('/api/v1/todos', {todo: {title: this.getTitle.value}})
|
||||
.then(response => {
|
||||
this.props.dispatch(addTodo(response.data.id, response.data.title))
|
||||
this.getTitle.value = '';
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
|
||||
updateTodo = (e, id) => {
|
||||
axios.put(`/api/v1/todos/${id}`, {todo: {done: e.target.checked}})
|
||||
.then(response => {
|
||||
this.props.dispatch(toggleTodo(id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
deleteTodo = (id) => {
|
||||
axios.delete(`/api/v1/todos/${id}`)
|
||||
.then(response => {
|
||||
this.props.dispatch(deleteTodo(id))
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getTodos();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="header">
|
||||
<h1>Todo List</h1>
|
||||
</div>
|
||||
<div className="inputContainer">
|
||||
<input className="taskInput" type="text" placeholder="Add a task" maxLength="50"
|
||||
onKeyPress={this.createTodo} ref={(input)=>this.getTitle = input} />
|
||||
</div>
|
||||
<div className="listWrapper">
|
||||
<ul className="taskList">
|
||||
{this.props.todos.map((todo) => {
|
||||
return(
|
||||
<li className="task" key={todo.id} id={todo.id}>
|
||||
<input className="taskCheckbox" type="checkbox"
|
||||
checked={todo.done} onChange={(e) => this.updateTodo(e, todo.id)} />
|
||||
<label className="taskLabel">{todo.title}</label>
|
||||
<span className="deleteTaskBtn" onClick={(e) => this.deleteTodo(todo.id)}>
|
||||
x
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
todos: state.todos
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TodosContainer)
|
||||
|
|
@ -3,7 +3,6 @@ import todosReducer from './todosReducer'
|
|||
|
||||
const rootReducer = combineReducers({
|
||||
todos: todosReducer
|
||||
// todosReducer
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
Loading…
Add table
Reference in a new issue