Silly task tracker to track silly things for silly friend
silly.bwc9876.dev
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}