Silly task tracker to track silly things for silly friend silly.bwc9876.dev
at main 78 lines 2.1 kB view raw
1import { useEffect, useState } from "react"; 2 3import silly from "./assets/silly.png"; 4import Entry from "./Entry"; 5 6export type Entry = { id: number; name: string; progress: number }; 7type State = Entry[]; 8 9const current = JSON.parse(window.localStorage.getItem("state") ?? "[]") as State; 10 11export default function App() { 12 const [guyVal, setGuy] = useState(""); 13 const [state, setState] = useState<State>(current); 14 15 const addGuy = () => { 16 setState((s) => { 17 const newId = Math.random() * Number.MAX_SAFE_INTEGER; 18 const newState = [{ id: newId, name: guyVal, progress: 0 }, ...s]; 19 return newState.sort((a, b) => { 20 if (a.name === b.name) { 21 return a.id - b.id; 22 } else { 23 return a.name < b.name ? -1 : 1; 24 } 25 }); 26 }); 27 setGuy(""); 28 }; 29 30 useEffect(() => { 31 window.localStorage.setItem("state", JSON.stringify(state)); 32 }, [state]); 33 34 useEffect(() => { 35 const handler = (e: { key: string }) => { 36 if (e.key === "Enter" && guyVal !== "") { 37 addGuy(); 38 } 39 }; 40 41 document.addEventListener("keydown", handler); 42 43 return () => { 44 document.removeEventListener("keydown", handler); 45 }; 46 }, [addGuy]); 47 48 return ( 49 <> 50 <h1> 51 <img src={silly} width="200" height="200" alt="Silly kitty cat with tongue out" /> 52 Silly Task Tracker 53 <img src={silly} width="200" height="200" alt="Silly kitty cat with tongue out" /> 54 </h1> 55 <label htmlFor="add">Add New Task</label> 56 <input 57 id="add" 58 value={guyVal} 59 onChange={(e) => setGuy(e.target.value)} 60 type="text" 61 placeholder="homework" 62 /> 63 <button disabled={guyVal === ""} onClick={addGuy}> 64 Add 65 </button> 66 <div className="list"> 67 {state.map((e, i) => ( 68 <Entry 69 key={e.id} 70 onDelete={() => setState((s) => s.filter((_, j) => j !== i))} 71 onChange={(newVal) => setState((s) => s.with(i, { ...e, progress: newVal }))} 72 {...e} 73 /> 74 ))} 75 </div> 76 </> 77 ); 78}