-
Notifications
You must be signed in to change notification settings - Fork 47
Solution: Brahim Benalia & Marc Solà Ramos #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e62f1b0
6dd2cd4
981ce8e
5286b83
d008242
d0c0d5e
951c883
46be3e4
09b2b56
76d3ee7
8888a3a
fe07b42
f88be24
d6e71a4
adb06d1
382eda3
04c4cf0
71d6f7b
8150b2f
d123748
ca59f19
80a529e
5396d33
06c5687
9ae541b
3f52101
b7e85e7
c1e6af6
17dc67c
5cc9f99
0366fd7
9034f87
3057a70
a1731a2
72e806f
8df14ad
b92ec1c
69b7cba
fa18bf5
475e27e
5ce8f7f
3e512e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,215 @@ | ||
import React from "react"; | ||
|
||
function App() { | ||
return ( | ||
<main className="container mt-5"> | ||
<section className="row"> | ||
<div className="col col-12"> | ||
<h1>Hola mundo</h1> | ||
</div> | ||
</section> | ||
</main> | ||
); | ||
import React, { Component } from "react"; | ||
import classNames from "classnames"; | ||
import { Route } from "react-router-dom"; | ||
import { v4 as uuidv4 } from "uuid"; | ||
|
||
import TodoList from "./components/TodoList"; | ||
import * as api from "./api"; | ||
import AppHeader from "./components/AppHeader"; | ||
|
||
import { HOME, ACTIVE, COMPLETED } from "./constatnts/routes"; | ||
|
||
import "./app.scss"; | ||
|
||
const LOCAL_STORAGE_KEY = "todo-state"; | ||
|
||
function loadLocalStorageData() { | ||
const prevItems = localStorage.getItem(LOCAL_STORAGE_KEY); | ||
|
||
if (!prevItems) { | ||
return null; | ||
} | ||
|
||
try { | ||
return JSON.parse(prevItems); | ||
} catch (error) { | ||
return null; | ||
} | ||
} | ||
|
||
class App extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
todos: [], | ||
todoName: "", | ||
currentTheme: false, | ||
}; | ||
this.handleAddTodo = this.handleAddTodo.bind(this); | ||
this.handleSubmit = this.handleSubmit.bind(this); | ||
this.handleChange = this.handleChange.bind(this); | ||
this.handleRemove = this.handleRemove.bind(this); | ||
this.handleChangeCheck = this.handleChangeCheck.bind(this); | ||
this.handleEdit = this.handleEdit.bind(this); | ||
this.handleEditSubmit = this.handleEditSubmit.bind(this); | ||
this.handleResetEdit = this.handleResetEdit.bind(this); | ||
this.handleClearCompleted = this.handleClearCompleted.bind(this); | ||
this.handleThemeClick = this.handleThemeClick.bind(this); | ||
} | ||
|
||
componentDidMount() { | ||
const prevItems = loadLocalStorageData(); | ||
|
||
if (!prevItems || !prevItems.todos.length) { | ||
api.getProducts().then((data) => { | ||
this.setState({ todos: data }); | ||
}); | ||
return; | ||
} | ||
|
||
this.setState({ | ||
todos: prevItems.todos, | ||
currentTheme: prevItems.currentTheme, | ||
}); | ||
} | ||
|
||
componentDidUpdate() { | ||
const { todos, currentTheme } = this.state; | ||
localStorage.setItem( | ||
LOCAL_STORAGE_KEY, | ||
JSON.stringify({ todos, currentTheme }), | ||
); | ||
} | ||
|
||
handleAddTodo(values) { | ||
const { todos } = this.state; | ||
|
||
const newTodo = { | ||
id: uuidv4(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Muy buen uso de uuid para crear ids 👏🏻 |
||
name: values.name, | ||
complete: false, | ||
}; | ||
|
||
this.setState({ todos: [...todos, newTodo], todoName: "" }); | ||
} | ||
|
||
handleSubmit(e) { | ||
e.preventDefault(); | ||
this.handleAddTodo(this.state); | ||
} | ||
|
||
handleChange(e) { | ||
this.setState({ todoName: e.target.value }); | ||
} | ||
|
||
handleRemove(id) { | ||
const { todos } = this.state; | ||
const arr = todos.filter((todo) => todo.id !== id); | ||
this.setState({ todos: arr }); | ||
} | ||
|
||
handleChangeCheck(id) { | ||
const { todos } = this.state; | ||
const arr = todos.map((todo) => { | ||
return todo.id === id ? { ...todo, complete: !todo.complete } : todo; | ||
// return obj; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Este código comentado se debería eliminar ya que no se usa |
||
}); | ||
|
||
this.setState({ todos: arr }); | ||
} | ||
|
||
handleClearCompleted() { | ||
const { todos } = this.state; | ||
const arr = todos.filter((todo) => todo.complete === false); | ||
this.setState({ todos: arr }); | ||
} | ||
|
||
handleEdit(id) { | ||
const { todos } = this.state; | ||
const todoToEdit = todos.map((todo) => { | ||
return todo.id === id ? { ...todo, edit: true } : todo; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Muy bueno uso del operador ternario para la comprobación 👏🏻 |
||
}); | ||
this.setState({ todos: todoToEdit }); | ||
} | ||
|
||
handleEditSubmit(values, id) { | ||
const { todos } = this.state; | ||
const todoToEdit = todos.map((todo) => { | ||
return todo.id === id | ||
? { ...todo, name: values.name, edit: false } | ||
: todo; | ||
}); | ||
this.setState({ todos: todoToEdit }); | ||
} | ||
|
||
handleResetEdit() { | ||
const { todos } = this.state; | ||
const todoToEdit = todos.map((todo) => { | ||
return { ...todo, edit: false }; | ||
}); | ||
this.setState({ todos: todoToEdit }); | ||
} | ||
|
||
handleThemeClick() { | ||
const { currentTheme } = this.state; | ||
this.setState({ currentTheme: !currentTheme }); | ||
} | ||
|
||
render() { | ||
const { todos, currentTheme } = this.state; | ||
const appClasses = classNames({ | ||
globalContainer: true, | ||
darkModeOpacity: currentTheme, | ||
}); | ||
|
||
return ( | ||
<div className={appClasses}> | ||
<AppHeader | ||
handleAddTodo={this.handleAddTodo} | ||
handleThemeClick={this.handleThemeClick} | ||
currentTheme={currentTheme} | ||
/> | ||
|
||
<Route | ||
path={ACTIVE} | ||
exact | ||
render={(routeProps) => ( | ||
<TodoList | ||
{...routeProps} | ||
handleChangeCheck={this.handleChangeCheck} | ||
handleRemove={this.handleRemove} | ||
todos={todos.filter((todo) => !todo.complete)} | ||
handleClearCompleted={this.handleClearCompleted} | ||
currentTheme={currentTheme} | ||
/> | ||
)} | ||
/> | ||
|
||
<Route | ||
path={COMPLETED} | ||
exact | ||
render={(routeProps) => ( | ||
<TodoList | ||
{...routeProps} | ||
handleChangeCheck={this.handleChangeCheck} | ||
handleRemove={this.handleRemove} | ||
todos={todos.filter((todo) => todo.complete)} | ||
handleClearCompleted={this.handleClearCompleted} | ||
currentTheme={currentTheme} | ||
/> | ||
)} | ||
/> | ||
|
||
<Route | ||
path={HOME} | ||
exact | ||
render={(routeProps) => ( | ||
<TodoList | ||
{...routeProps} | ||
handleChangeCheck={this.handleChangeCheck} | ||
handleRemove={this.handleRemove} | ||
handleEdit={this.handleEdit} | ||
handleEditSubmit={this.handleEditSubmit} | ||
handleResetEdit={this.handleResetEdit} | ||
handleClearCompleted={this.handleClearCompleted} | ||
todos={todos} | ||
currentTheme={currentTheme} | ||
/> | ||
)} | ||
/> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default App; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Muy interesante el check para ver si el localstorage tiene todos o no.