Skip to content

Instantly share code, notes, and snippets.

@esDotDev
Created December 8, 2022 19:55
Show Gist options
  • Save esDotDev/0682dd9881e444a6a182e67ffddc1d17 to your computer and use it in GitHub Desktop.
Save esDotDev/0682dd9881e444a6a182e67ffddc1d17 to your computer and use it in GitHub Desktop.
// Controller
class TodoController {
constructor(api) {
this.api = api;
}
async getAllTodos() {
const todos = await this.api.getAllTodos();
return todos;
}
async createTodo(data) {
const todo = await this.api.createTodo(data);
return todo;
}
async updateTodo(id, data) {
const todo = await this.api.updateTodo(id, data);
return todo;
}
async deleteTodo(id) {
const todo = await this.api.deleteTodo(id);
return todo;
}
}
// React Component
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [],
newTodoTitle: ""
};
this.controller = new TodoController(props.api);
}
async componentDidMount() {
const todos = await this.controller.getAllTodos();
this.setState({ todos });
}
handleNewTodoTitleChange = event => {
this.setState({ newTodoTitle: event.target.value });
};
handleTodoCreate = async () => {
const newTodo = await this.controller.createTodo({
title: this.state.newTodoTitle
});
const todos = [...this.state.todos, newTodo];
this.setState({ todos, newTodoTitle: "" });
};
handleTodoUpdate = async (id, data) => {
const updatedTodo = await this.controller.updateTodo(id, data);
const todos = this.state.todos.map(todo => {
if (todo.id === id) {
return updatedTodo;
}
return todo;
});
this.setState({ todos });
};
handleTodoDelete = async id => {
await this.controller.deleteTodo(id);
const todos = this.state.todos.filter(todo => todo.id !== id);
this.setState({ todos });
};
render() {
return (
<div>
<h1>Todo App</h1>
<input
type="text"
value={this.state.newTodoTitle}
onChange={this.handleNewTodoTitleChange}
/>
<button onClick={this.handleTodoCreate}>Create Todo</button>
{this.state.todos.map(todo => (
<Todo
key={todo.id}
todo={todo}
onUpdate={this.handleTodoUpdate}
onDelete={this.handleTodoDelete}
/>
))}
</div>
);
}
}
const Todo = ({ todo, onUpdate, onDelete }) => {
const [isEditing, setIsEditing] = React.useState(false);
const [title, setTitle] = React.useState(todo.title);
const handleTitleChange = event => setTitle(event.target.value);
const handleUpdate = async () => {
await onUpdate(todo.id, { title });
setIsEditing(false);
};
const handleDelete = () => {
onDelete(todo.id);
};
if (isEditing) {
return (
<div>
<input type="text" value={title} onChange={handleTitleChange} />
<button onClick={handleUpdate}>Save</button>
<button onClick={() => setIsEditing(false)}>Cancel</button>
</div>
);
}
return (
<div>
<span>{title}</span>
<button onClick={() => setIsEditing(true)}>Edit</button>
<button onClick={handleDelete}>Delete</button>
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment