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

commits no enviados?? #29

Open
wants to merge 19 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
38 changes: 0 additions & 38 deletions src/App.css

This file was deleted.

25 changes: 0 additions & 25 deletions src/App.js

This file was deleted.

47 changes: 47 additions & 0 deletions src/App/AppUI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { TodoCount } from '../TodoCount';
import { TodoSearch } from '../TodoSearch';
import { TodoList } from '../TodoList';
import { TodoItem } from '../TodoItem';
import { TodoButton } from '../TodoButton';

function AppUI({
loading, //recibimos como prop
error, //recibimos como prop
completeTodo, // Propiedad que se espera y se asigna a la variable completeTodo
totalTodos, // Propiedad que se espera y se asigna a la variable totalTodos
searchValue, setSearchValue, // Propiedades que se esperan y se asignan a las variables searchValue y setSearchValue
searchedTodos, // Propiedad que se espera y se asigna a la variable searchedTodos
completedTodos, deleteTodo, // Propiedades que se esperan y se asignan a las variables completedTodos y deleteTodo
}) {
return ( // a partir de aqui no estamos incorporando html, sino JSX
<> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/}
{/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */}
<TodoCount completed={completedTodos} total={totalTodos}/>
<TodoSearch
searchValue={searchValue}
setSearchValue={setSearchValue}
/>

<TodoList>
{loading && <p>Estamos cargando...</p>} {/*mensaje que aparecera si se esta cargando */}
{error && <p>Hubo un error.</p>} {/* mensaje que aparecera si hay un error */}
{(!loading && searchedTodos.length == 0) && <p>Crea tu primer TODO</p>}
{/* (si no se esta cargando y la longitud de los todos es igual a 0) entonces aparecera un mensaje que dira 'crea tu todo' */}

{searchedTodos.map(todo =>(
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
onComplete={() => completeTodo(todo.text)} //evento del onClick del archivo TodoItem
onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem
/>
))}
</TodoList>

<TodoButton/>
</>
);
}

export { AppUI }
80 changes: 80 additions & 0 deletions src/App/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* eslint-disable eqeqeq */
// eslint-disable-next-line no-unused-vars
import React from 'react';
import { useLocalStorage } from './useLocalStorage'
import { AppUI } from './AppUI'

function App() {
// Usa la función useLocalStorage para gestionar un elemento llamado 'TODOS_V1' en el localStorage
const {
item: todos,//se renombran
saveItem: saveTodos,//se renombran
loading,
error} = useLocalStorage('TODOS_V1', []); // Los corchetes vacíos indican que el valor inicial es un arreglo vacío
// 'todos' almacena el estado actual del elemento 'TODOS_V1' en el localStorage
// 'saveTodos' es la función que permite actualizar el estado de 'todos' y el localStorage

const [searchValue, setSearchValue] = React.useState('');

const completedTodos = todos.filter(todo => !!todo.completed).length;
//Para filtrar un elemento de un array (manipulacion de arrays) existen dos formas: find y filter. Find te permite filtrar un elemento, UN solo eelemento lo cual va a ser el primero de una lista, en cambio del filter; te filtrara TODOS los elemntos de una lista
//segundo; se hace una arrowFutsion; '(todo => todo.completed)' se llama -todo- a aquellos todos que tengan el estado -completed- como true. Pero a simple vista se ve que va a llamar es a un valor, y nosotros necesitamos un buleano, por lo tanto se escribe con doble explamacion, para que esos valores se transformen en boleano '(todo => !!todo.completed)'
//tercero; se pone la propiedad 'lwngth' para recibir las cantidades del array que se quiere filtrar
const totalTodos = todos.length; //contador de todos en total



const searchedTodos = todos.filter( //estado derivado de buscar todos
(todo) => { //arrow futsion
//return todo.text.toLowerCase().includes(searchValue.toLowerCase())
//aqui estamos preguntando si por cada 'todo'; si el texto (text) de ese todo incluye (includes) en alñguna parte ese texto que forma parte del searchValue
//el codigo '.toLowerCase()' convuerte toda aquellas minusculas a mayusculas y viceversa, o mejor dicho hace mas facil la busqueda de todos
//esta es una linea de codigo larga o mejor dicho de JavaScript moderno, para ordenarnos mas nos guiamos con la de abajo ↓

const todoText = todo.text.toLowerCase();
const searchText = searchValue.toLowerCase();
return todoText.includes(searchText);
}
);

const completeTodo = (text) => {
console.log('click'); // Imprime 'click' en la consola cada vez que se llama a la función

const newTodos = [...todos]; // Crea una copia de la matriz todos con '...'
const todoIndex = newTodos.findIndex(
(todo) => todo.text === text
); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado

newTodos[todoIndex].completed = true; // Marca la tarea encontrada como completada
saveTodos(newTodos); // Guarda y actualiza la lista de tareas
};

const deleteTodo = (text) => {
console.log('click delete'); // Imprime 'click delete' en la consola

const newTodos = [...todos]; // Crea una copia de la matriz todos
const todoIndex = newTodos.findIndex(
(todo) => todo.text === text
); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado

newTodos.splice(todoIndex, 1); // Elimina la tarea en el índice todoIndex de la matriz newTodos
saveTodos(newTodos); // Guarda y actualiza la lista de tareas
};

return ( // Devuelve un elemento JSX
<AppUI
loading={loading}
error={error}
completeTodo={completeTodo} // Prop completeTodo se asigna a la función completeTodo
totalTodos={totalTodos} // Prop totalTodos se asigna a la variable totalTodos
searchValue={searchValue} // Prop searchValue se asigna a la variable searchValue
setSearchValue={setSearchValue} // Prop setSearchValue se asigna a la función setSearchValue
searchedTodos={searchedTodos} // Prop searchedTodos se asigna a la variable searchedTodos
completedTodos={completedTodos} // Prop completedTodos se asigna a la variable completedTodos
deleteTodo={deleteTodo} // Prop deleteTodo se asigna a la función deleteTodo
/>
);

}

export default App;
40 changes: 40 additions & 0 deletions src/App/useLocalStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';

// Esta función maneja el uso del localStorage para un elemento específico
function useLocalStorage(itemName, initialValue) {
const [item, setItem] = React.useState(initialValue);
const [loanding, setLoanding] = React.useState(true); //estado de cargando
const [error, setError] = React.useState(false); //estado de error

React.useEffect(() => { //ahora es asincrona (se demorara)
// Extrae el elemento del localStorage
const localStorageItem = localStorage.getItem(itemName);

let parsedItem;

// Comprueba si no hay datos en el localStorage
if (!localStorageItem) {
// Si no hay datos, establece el valor inicial y lo almacena en el localStorage
localStorage.setItem(itemName, JSON.stringify(initialValue));
parsedItem = initialValue; // Establece el valor inicial
} else {
// Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse()
parsedItem = JSON.parse(localStorageItem);
}
});

// Función para guardar un nuevo item en el localStorage y actualizar el estado
const saveItem = (newItem) => {
localStorage.setItem(itemName, JSON.stringify(newItem));
setItem(newItem);
};

return {
item,
saveItem,
loanding,
error
}; // si tenemos mas de DOS ELEMENTOS que queremos RETORNAR dentro de los CustomHoocks; es mucho mas recomendable que enviemos un objeto{} que un array()
}

export { useLocalStorage }
16 changes: 16 additions & 0 deletions src/TodoButton/TodoButton.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
button{
position: fixed;
bottom: 20px;
height: auto;
right: 20px;
background-color: #fff0ac;
border: none;
border-radius: 50%;
font-size: 70px;
padding: 5px 30px;
margin: 30px;
font-family: ui-monospace;
font-weight: bold;
color: #1b191cb5;
box-shadow: 0 0 20px #d8ad7c;
}
13 changes: 13 additions & 0 deletions src/TodoButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import './TodoButton.css';

function TodoButton() {
return (
<button type="" onClick = { //funcion anonima de js en JSX con OnClick
() => {
return console.log('Le diste click al boton');
}
}>+</button>
)
}

export {TodoButton}
8 changes: 8 additions & 0 deletions src/TodoCount/TodoCount.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
h1 {
text-align: center;
font-family: emoji;
font-size: 50px;
text-shadow: 0 0 5px #d8ad7c;
color: wheat;
margin: 50px;
}
10 changes: 10 additions & 0 deletions src/TodoCount/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import './TodoCount.css';
function TodoCount({total, completed}){
return(
<h1 style={{

}}>Ya completaste {completed} de {total} TODO's</h1>
)
}

export {TodoCount}
14 changes: 14 additions & 0 deletions src/TodoIcon/CompleteIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { TodoIcon } from './index.js' //Importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js.

function CompleteIcon({completed, onComplete}) {
return (
<TodoIcon //Define el componente CompleteIcon. Este componente renderiza el componente TodoIcon con las propiedades type='check' y color='green'.
type='check'
color={completed ? 'green' : 'gray'} //si la propiedad completed es true, entonces se pone de colo verde... si no, se pone de color gris
onClick={onComplete} // funcion del click
/> // se encarga de mostrar un ícono de verificación (check) para representar la acción de completar una tarea.
)
}

export { CompleteIcon } //Exporta el componente CompleteIcon para su uso en otras partes de la aplicación.
14 changes: 14 additions & 0 deletions src/TodoIcon/DeleteIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { TodoIcon } from '../TodoIcon' //Se importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js.

function DeleteIcon({onDelete}) { //Define el componente DeleteIcon. Este componente renderiza el componente TodoIcon con las propiedades type='delete' y color='red'
return (
<TodoIcon
type='delete'
color='gray'
onClick={onDelete} // funcion del click
/>
) // DeleteIcon se encarga de mostrar un ícono de eliminación para representar la acción de borrar o eliminar una tarea de la lista. Además, intenta pasar una propiedad de color 'red', aunque en el código del componente TodoIcon no se está utilizando explícitamente la propiedad de color.
}

export { DeleteIcon } //Exporta el componente DeleteIcon para su uso en otras partes de la aplicación.
40 changes: 40 additions & 0 deletions src/TodoIcon/TodoIcon.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*estilos css SOLAMENTE paar los icons*/
.Icon-container{
cursor:pointer;
display:flex;
justify-content:center;
align-items:center;
height:48px;
width:48px;
font-size:24px;
font-weight:700
}

.Icon-container-check{
position:absolute;
left:12px
}.Icon-container-check--active{
color:#4caf50
}

.Icon-container-delete{
position:absolute;
top:-24px;
right:0
}.Icon-container-delete:hover{color:red}


.Icon-svg{
width: 20px;
height: 20px;
}

/*pdemos camviarle el color de los icons creados o aplicados en react, desde css
para que se vean como si estuvieramos usando un propiedad "color" pero en realidad se lo estamos modificando.
En este caso le estamos cambiando el color de los icons cuando el cursor este por encima de ellos*/
.Icon-container-check:hover .Icon-svg {
fill:green;
}
.Icon-container-delete:hover .Icon-svg {
fill:red;
}
Loading