Guest User

Untitled

a guest
Nov 4th, 2026
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 2.73 KB | Source Code | 0 0
  1. "use client";
  2.  
  3. import { useEffect, useState } from "react";
  4.  
  5. type Task = { userId: string; taskId: string; title: string; done: boolean; createdAt: string };
  6.  
  7. export default function Home() {
  8.   const [userId, setUserId] = useState("alice");
  9.   const [tasks, setTasks] = useState<Task[]>([]);
  10.   const [title, setTitle] = useState("");
  11.   const [version, setVersion] = useState(0); // bump to reload the list
  12.   const reload = () => setVersion((v) => v + 1);
  13.  
  14.   // Load the user's tasks whenever the user changes or after any write
  15.   useEffect(() => {
  16.     let cancelled = false;
  17.     fetch(`/api/tasks?userId=${encodeURIComponent(userId)}`)
  18.       .then((res) => res.json())
  19.       .then((data) => !cancelled && setTasks(data));
  20.     return () => {
  21.       cancelled = true;
  22.     };
  23.   }, [userId, version]);
  24.  
  25.   async function addTask(e: React.FormEvent) {
  26.     e.preventDefault();
  27.     if (!title.trim()) return;
  28.     await fetch("/api/tasks", {
  29.       method: "POST",
  30.       headers: { "Content-Type": "application/json" },
  31.       body: JSON.stringify({ userId, title }),
  32.     });
  33.     setTitle("");
  34.     reload();
  35.   }
  36.  
  37.   async function toggle(t: Task) {
  38.     await fetch(`/api/tasks/${t.taskId}`, {
  39.       method: "PATCH",
  40.       headers: { "Content-Type": "application/json" },
  41.       body: JSON.stringify({ userId, done: !t.done }),
  42.     });
  43.     reload();
  44.   }
  45.  
  46.   async function remove(t: Task) {
  47.     await fetch(`/api/tasks/t.taskId?userId={encodeURIComponent(userId)}`, { method: "DELETE" });
  48.     reload();
  49.   }
  50.  
  51.   return (
  52.     <main style={{ maxWidth: 560, margin: "40px auto", fontFamily: "system-ui", padding: "0 16px" }}>
  53.       <h1>Task App (DynamoDB)</h1>
  54.  
  55.       <label>
  56.         User:{" "}
  57.         <select value={userId} onChange={(e) => setUserId(e.target.value)}>
  58.           <option>alice</option>
  59.           <option>bob</option>
  60.         </select>
  61.       </label>
  62.  
  63.       <form onSubmit={addTask} style={{ display: "flex", gap: 8, margin: "16px 0" }}>
  64.         <input
  65.           value={title}
  66.           onChange={(e) => setTitle(e.target.value)}
  67.           placeholder="New task"
  68.           style={{ flex: 1, padding: 8 }}
  69.         />
  70.         <button>Add</button>
  71.       </form>
  72.  
  73.       <ul style={{ listStyle: "none", padding: 0 }}>
  74.         {tasks.map((t) => (
  75.           <li key={t.taskId} style={{ display: "flex", gap: 8, padding: "8px 0", borderBottom: "1px solid #ddd" }}>
  76.             <input type="checkbox" checked={t.done} onChange={() => toggle(t)} />
  77.             <span style={{ flex: 1, textDecoration: t.done ? "line-through" : "none" }}>{t.title}</span>
  78.             <button onClick={() => remove(t)}>Delete</button>
  79.           </li>
  80.         ))}
  81.       </ul>
  82.       <p>{tasks.length} task(s) for {userId}</p>
  83.     </main>
  84.   );
  85. }
  86.  
Advertisement
Add Comment
Please, Sign In to add comment