Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- "use client";
- import { useEffect, useState } from "react";
- type Task = { id: number; title: string; done: boolean; created_at: string };
- type Health = { server: string; version: string };
- export default function Home() {
- const [tasks, setTasks] = useState<Task[]>([]);
- const [health, setHealth] = useState<Health | null>(null);
- const [title, setTitle] = useState("");
- const [error, setError] = useState("");
- const [version, setVersion] = useState(0); // bump to reload
- const reload = () => setVersion((v) => v + 1);
- // Load tasks and server info on start and after any write
- useEffect(() => {
- let cancelled = false;
- Promise.all([fetch("/api/tasks"), fetch("/api/health")])
- .then(async ([t, h]) => {
- if (!t.ok || !h.ok) throw new Error("Database request failed");
- const [taskData, healthData] = await Promise.all([t.json(), h.json()]);
- if (!cancelled) {
- setTasks(taskData);
- setHealth(healthData);
- setError("");
- }
- })
- .catch((e) => !cancelled && setError(e.message));
- return () => {
- cancelled = true;
- };
- }, [version]);
- async function addTask(e: React.FormEvent) {
- e.preventDefault();
- if (!title.trim()) return;
- await fetch("/api/tasks", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ title }),
- });
- setTitle("");
- reload();
- }
- async function toggle(t: Task) {
- await fetch(`/api/tasks/${t.id}`, {
- method: "PATCH",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ done: !t.done }),
- });
- reload();
- }
- async function remove(t: Task) {
- await fetch(`/api/tasks/${t.id}`, { method: "DELETE" });
- reload();
- }
- return (
- <main style={{ maxWidth: 560, margin: "40px auto", fontFamily: "system-ui", padding: "0 16px" }}>
- <h1>Task App (Amazon RDS MySQL)</h1>
- <p style={{ color: "#666" }}>
- {health ? `Served by ${health.server} · MySQL ${health.version}` : "Connecting…"}
- </p>
- {error && <p style={{ color: "crimson" }}>{error}</p>}
- <form onSubmit={addTask} style={{ display: "flex", gap: 8, margin: "16px 0" }}>
- <input
- value={title}
- onChange={(e) => setTitle(e.target.value)}
- placeholder="New task"
- style={{ flex: 1, padding: 8 }}
- />
- <button>Add</button>
- </form>
- <ul style={{ listStyle: "none", padding: 0 }}>
- {tasks.map((t) => (
- <li key={t.id} style={{ display: "flex", gap: 8, padding: "8px 0", borderBottom: "1px solid #ddd" }}>
- <input type="checkbox" checked={t.done} onChange={() => toggle(t)} />
- <span style={{ flex: 1, textDecoration: t.done ? "line-through" : "none" }}>{t.title}</span>
- <button onClick={() => remove(t)}>Delete</button>
- </li>
- ))}
- </ul>
- <p>{tasks.length} task(s)</p>
- </main>
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment