Fixed code of todo list (ts)

 avatar
unknown
typescript
3 years ago
3.0 kB
4
Indexable
import { useEffect, useState } from "react";

type Props = {
   todos?: TodoItem[];
};

type TodoItem = {
   id: string | number;
   title: string | null;
   isDone?: boolean;
};

const App = (props?: Props) => {
   const [todos, setTodos] = useState<TodoItem[]>(props?.todos || []);
   const [filter, setFilter] = useState<"all" | "undone">("all");
   const [doneCount, setDoneCount] = useState(0);

   useEffect(() => {
      if (props?.todos?.length) {
         setFilter("all");
      }
   });

   console.log(todos);
   

   const addTodo = (title?: string | null) => {
      if (!title) {
         title = prompt("What to do?");
      }
      if (!title) return;
      setTodos(
         todos.concat({
          id: +Date.now(),
          title,
       })
      );
   };

   const markAsDone = (todo: TodoItem) => {
     const index = todos.findIndex( el => el.id === todo.id);

      if (index >= 0) {
        setTodos(todos.map((td, ind) => ind === index ? { ...td, isDone: true } : td));
        setDoneCount(doneCount + 1);
      }

   };

   const markAsUndone = (todo: TodoItem) => {
      const index = todos.findIndex( item => item.id === todo.id);

      if (index >= 0) {
         setTodos(todos.map((td, ind) => (ind === index ? { ...td, isDone: false } : td)));
         setDoneCount(doneCount - 1);
      }

   };

   const deleteTodo = (todo: TodoItem) => {
      const index = todos.indexOf(todo);

      if (index >= 0) {
         setTodos(todos.slice(0, index).concat(todos.slice(index + 1)));
         todo.isDone && setDoneCount(doneCount - 1);
      }

   };

   const onFilterButtonClick = () => {
      setFilter(filter !== "all" ? "all" : "undone");
   };

   return (
      <div>
         <p>{`${doneCount} / ${todos.length}`}</p>
         <ul>
            {todos
               .filter((todo) => filter !== "undone"  || !todo.isDone)
               .map((todo) => (
                  <div key={`${todo.id}`}>
                     <p>{`${todo.isDone ? "✅ " : ""}${todo.title}`}</p>
                     <button
                        onClick={() => {
                           !todo.isDone ? markAsDone(todo) : markAsUndone(todo);
                        }}
                     >
                        {"Done"}
                     </button>
                     <button onClick={() => deleteTodo(todo)}>{"Delete"}</button>
                  </div>
               ))}
         </ul>
         <button onClick={() => addTodo()}>{"Add"}</button>
         <button onClick={() => onFilterButtonClick()}>
            {`Show ${filter === "all" ? "undone" : "all"} todos`}
         </button>
         {/* <ExpensiveTree /> */}
      </div>
   );
};

function ExpensiveTree() {
   let now = performance.now();

   while (performance.now() - now < 1000) {
      // Artificial delay -- do nothing for 1000ms
   }

   return null;
}

export default App;