| 1 | import { env } from "../../src/Env.ts"; |
| 2 | import { Card } from "../components/Card"; |
| 3 | import { LocalTime } from "../components/LocalTime"; |
| 4 | import { NoteDelete, NotesForm } from "./notes-form"; |
| 5 | |
| 6 | export const dynamic = "force-dynamic"; |
| 7 | |
| 8 | type Note = { |
| 9 | id: string; |
| 10 | title: string; |
| 11 | createdAt: number; |
| 12 | }; |
| 13 | |
| 14 | async function loadNotes(): Promise<Note[]> { |
| 15 | const res = await env.BACKEND.fetch(new Request("http://localhost/notes")); |
| 16 | if (!res.ok) { |
| 17 | throw new Error(`list failed: ${res.status}`); |
| 18 | } |
| 19 | const body = (await res.json()) as { notes: Note[] }; |
| 20 | return body.notes; |
| 21 | } |
| 22 | |
| 23 | export default async function NotesPage() { |
| 24 | const notes = await loadNotes(); |
| 25 | |
| 26 | return ( |
| 27 | <Card title="Notes"> |
| 28 | <div className="space-y-4"> |
| 29 | <NotesForm /> |
| 30 | <ul data-testid="note-list" className="space-y-2 text-sm"> |
| 31 | {notes.length === 0 ? ( |
| 32 | <li className="text-slate-500">No notes yet.</li> |
| 33 | ) : ( |
| 34 | notes.map((note) => ( |
| 35 | <li |
| 36 | key={note.id} |
| 37 | className="flex items-center justify-between gap-3 rounded-md border border-slate-200 bg-white px-3 py-2" |
| 38 | > |
| 39 | <div className="min-w-0"> |
| 40 | <div>{note.title}</div> |
| 41 | <div className="mt-0.5 text-xs text-slate-500"> |
| 42 | <LocalTime value={note.createdAt} /> |
| 43 | </div> |
| 44 | </div> |
| 45 | <NoteDelete id={note.id} /> |
| 46 | </li> |
| 47 | )) |
| 48 | )} |
| 49 | </ul> |
| 50 | </div> |
| 51 | </Card> |
| 52 | ); |
| 53 | } |