Skip to content
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

Solución de José Peralta #45

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# MyDayApp - JavaScript

MyDayApp es una aplicación para gestionar tareas de forma sencilla, fácil y en donde pondrás a pruebas tus conocimientos en JS.
Esta es la solución realizada por José Peralta.

![preview](https://i.imgur.com/et5mmr7.png)

Expand Down
26 changes: 0 additions & 26 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,6 @@ <h1>My Day</h1>
<!-- This section should be hidden by default and shown when there are todos -->
<section class="main">
<ul class="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<li class="completed">
<div class="view">
<input class="toggle" type="checkbox" checked />
<label>Learn JavaScript</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Learn JavaScript" />
</li>
<li>
<div class="view">
<input class="toggle" type="checkbox" />
<label>Buy a unicorn</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Buy a unicorn" />
</li>
<li class="editing">
<div class="view">
<input class="toggle" type="checkbox" />
<label>Make dishes</label>
<button class="destroy"></button>
</div>
<input class="edit" value="Make dishes" />
</li>
</ul>
</section>
<!-- This footer should be hidden by default and shown when there are todos -->
Expand Down
121 changes: 119 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,122 @@
import "./css/base.css";
import { fetch, add, edit, toggleComplete, remove } from "./js/storage";
import { showMain, showFooter, showClearCompleted, showCounter, filterTodos } from "./js/render";

import { sayHello } from "./js/utils";
function getRoute() {
let re = /(?<=#)\/.*$/g;
let url = window.location.hash
let route;
if(window.location.hash === "") route = "/";
else route = url.slice(re.exec(url).index, url.length);

console.log(sayHello("Hello"));
return route;
}

function render(todos) {

let list = document.querySelector(".todo-list");
let route = getRoute();

showMain(todos.length === 0 ? "none" : "block");
showFooter(todos.length === 0 ? "none" : "block");
showClearCompleted(todos.some(todo=>todo.completed) ? "block" : "none");
showCounter(todos.filter((todo)=>!todo.completed).length);

while(list.hasChildNodes()) list.removeChild(list.lastChild);

filterTodos(todos, route).forEach((todo)=>{
let liTodo = document.createElement("li");
let view = document.createElement("div");
let completeButton = document.createElement("input");
let title = document.createElement("label");
let destroyButton = document.createElement("button");
let editInput = document.createElement("input");

completeButton.type = "checkbox";
completeButton.classList.add("toggle");

title.innerText = todo.title;

if(todo.completed) {
liTodo.classList.add("completed");
completeButton.checked = true;
};

destroyButton.classList.add("destroy");

editInput.classList.add("edit");

view.classList.add("view");

view.append(completeButton, title, destroyButton);
liTodo.append(view, editInput);


completeButton.addEventListener("click", ()=> toggleComplete(localStorageKey, todo.id));

destroyButton.addEventListener("click", ()=> remove(localStorageKey, todo.id));

editInput.addEventListener("keydown", (e)=>{
if(e.key === "Enter") {
if(e.target.value.trim() !== "") edit(localStorageKey, todo.id, e.target.value.trim());
}
else if(e.key === "Escape") {
editInput.style.display = "none";
liTodo.classList.remove("editing");
}
});

title.addEventListener("dblclick", ()=>{
editInput.style.display = "block";
editInput.value = title.innerText;
editInput.focus();
liTodo.classList.add("editing");
});

list.appendChild(liTodo);

});
}



function main() {
let todos = fetch(localStorageKey);
let createTodoInput = document.querySelector(".new-todo");
let clearCompleted = document.querySelector(".clear-completed");

render(todos);

createTodoInput.addEventListener("keydown", (e)=>{
if(e.key === "Enter") {
if(e.target.value.trim() !== "") {
let id;
todos = fetch(localStorageKey);
id = todos.length > 0 ? todos[todos.length-1].id + 1 : 0;
add(localStorageKey, {id, title: e.target.value.trim(), completed: false });
e.target.value = "";
}
}
});

window.addEventListener("storage", () => {
todos = fetch(localStorageKey);
render(todos);
});


window.addEventListener("hashchange", (e)=>{
todos = fetch(localStorageKey);
render(todos);
});

clearCompleted.addEventListener("click", ()=>{
todos = fetch(localStorageKey);
todos.forEach(todo => todo.completed ? remove(localStorageKey, todo.id) : false);
});
}

const localStorageKey = "mydayapp-js";


main();
51 changes: 51 additions & 0 deletions src/js/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
function fetch(localStorageKey) {
let todos = localStorage.getItem(localStorageKey);
if(todos !== null) {
return JSON.parse(todos);
}
localStorage.setItem(localStorageKey, "[]");
return [];
}

function add(localStorageKey, todo) {
let todos = localStorage.getItem(localStorageKey);
todos = JSON.parse(todos);
todos.push(todo);
localStorage.setItem(localStorageKey, JSON.stringify(todos));
window.dispatchEvent(new Event('storage'));
}

function remove(localStorageKey, todoid) {
let todos = localStorage.getItem(localStorageKey);
todos = JSON.parse(todos);
let todoIndex = todos.findIndex((todo)=>todo.id === todoid);
if (todoIndex !== -1) {
todos.splice(todoIndex, 1);
localStorage.setItem(localStorageKey, JSON.stringify(todos));
window.dispatchEvent(new Event('storage'));
}
}

function toggleComplete(localStorageKey, todoid) {
let todos = localStorage.getItem(localStorageKey);
todos = JSON.parse(todos);
let todoIndex = todos.findIndex((todo)=>todo.id === todoid);
if (todoIndex !== -1) {
todos[todoIndex].completed = !todos[todoIndex].completed;
localStorage.setItem(localStorageKey, JSON.stringify(todos));
window.dispatchEvent(new Event('storage'));
}
}

function edit(localStorageKey, todoid, text) {
let todos = localStorage.getItem(localStorageKey);
todos = JSON.parse(todos);
let todoIndex = todos.findIndex((todo)=>todo.id === todoid);
if (todoIndex !== -1) {
todos[todoIndex].title = text;
localStorage.setItem(localStorageKey, JSON.stringify(todos));
window.dispatchEvent(new Event('storage'));
}
}

export { fetch, add, edit, toggleComplete, remove};
3 changes: 0 additions & 3 deletions src/js/utils.js

This file was deleted.