import React, { Component } from 'react' import logo from './logo.svg' import github from './github.svg' import deployButton from './deploy-to-netlify.svg' import ContentEditable from './components/ContentEditable' import './App.css' class App extends Component { state = { todos: [] } componentDidMount() { console.log('fetch items') fetch('/.netlify/functions/todos-read-all') .then((response) => { console.log(response) return response.json() }) .then((myJson) => { console.log(myJson) this.setState({ todos: myJson }) }) } saveTodo = (e) => { e.preventDefault(); const { todos } = this.state const todoValue = this.inputElement.value if (!todoValue) { alert('Please add todo text') return false } // reset input to empty this.inputElement.value = '' // Optimistically add todo to UI const temporaryValue = { data: { title: todoValue } } const optimisticTodoState = todos.concat(temporaryValue) this.setState({ todos: optimisticTodoState }) // Make API request to create new todo fetch('/.netlify/functions/todos-create', { body: JSON.stringify({ title: todoValue }), method: 'POST', // mode: 'cors', // no-cors, cors, *same-origin }) .then(response => response.json()) .then((json) => { console.log(json) // remove temporaryValue from state and persist API response const persistedState = removeOptimisticTodo(todos).concat(json) // Set persisted value to state this.setState({ todos: persistedState }) // fin }).catch((e) => { console.log('An API error occurred', e) const revertedState = removeOptimisticTodo(todos) // Reset to original state this.setState({ todos: revertedState }) }) } deleteTodo = (e) => { const { todos } = this.state const todoId = e.target.dataset.id console.log(`Delete todo ${todoId}`) // Optimistically remove todo from UI const filteredTodos = todos.reduce((acc, current) => { const currentId = getTodoId(current) if (currentId === todoId) { // save item being removed for rollback acc.rollbackTodo = current return acc } // filter deleted todo out of the todos list acc.optimisticState = acc.optimisticState.concat(current) return acc }, { rollbackTodo: {}, optimisticState: [] }) this.setState({ todos: filteredTodos.optimisticState }) // Make API request to delete todo fetch(`/.netlify/functions/todos-delete/${todoId}`, { method: 'POST', }) .then(response => response.json()) .then((json) => { console.log(json) }).catch((e) => { console.log(`There was an error removing ${todoId}`, e) // Add item removed back to list this.setState({ todos: filteredTodos.optimisticState.concat(filteredTodos.rollbackTodo) }) }) } updateTodo = (id, todoValue) => { // Make API request to update todo fetch(`/.netlify/functions/todos-update/${id}`, { body: JSON.stringify({ title: todoValue }), method: 'POST', // mode: 'cors', // no-cors, cors, *same-origin }) .then(response => response.json()) .then((json) => { console.log(json) // fin }).catch((e) => { console.log('An API error occurred', e) }) } handleTodoToggle = (e) => { console.log('checkbox changed') console.log(e.target.checked); } handleDataChange = (event, currentValue) => { // save on change debounced? } handleBlur = (event, currentValue) => { let isDifferent = false const key = event.target.dataset.key const updatedTodos = this.state.todos.map((todo, i) => { const id = getTodoId(todo) if (id === key && todo.data.title !== currentValue) { todo.data.title = currentValue isDifferent = true } return todo }) // only set state if input different if (isDifferent) { this.setState({ todos: updatedTodos }, () => { this.updateTodo(key, currentValue) }) } } renderTodos() { const { todos } = this.state return todos.map((todo, i) => { const { data, ref } = todo const id = getTodoId(todo) // only show delete button after create API response returns let deleteButton if (ref) { deleteButton = ( ) } return (
Using FaunaDB & Netlify functions