This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// The project's notes, one row each. A server component: it holds no state, and every string is passed in.
|
||||
|
||||
import type { ReactElement } from "react"
|
||||
import type { NoteView } from "../contract/index.js"
|
||||
|
||||
export interface NoteListLabels {
|
||||
readonly caption: string
|
||||
readonly empty: string
|
||||
readonly note: string
|
||||
readonly attachments: string
|
||||
readonly updated: string
|
||||
/** `Open {title}`: the link's accessible name, so a list of links is not a list of the same word. */
|
||||
readonly open: string
|
||||
}
|
||||
|
||||
export function NoteList({
|
||||
notes,
|
||||
hrefFor,
|
||||
labels,
|
||||
formatDate,
|
||||
}: {
|
||||
notes: readonly NoteView[]
|
||||
hrefFor: (noteId: string) => string
|
||||
labels: NoteListLabels
|
||||
formatDate: (iso: string) => string
|
||||
}): ReactElement {
|
||||
if (notes.length === 0) {
|
||||
return <p data-guide="notes.note-list">{labels.empty}</p>
|
||||
}
|
||||
return (
|
||||
// guide: The notes of this project
|
||||
<table data-guide="notes.note-list">
|
||||
<caption>{labels.caption}</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{labels.note}</th>
|
||||
<th scope="col">{labels.attachments}</th>
|
||||
<th scope="col">{labels.updated}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{notes.map((note) => (
|
||||
<tr key={note.noteId}>
|
||||
<th scope="row">
|
||||
<a href={hrefFor(note.noteId)} aria-label={labels.open.replace("{title}", note.title)}>
|
||||
{note.title}
|
||||
</a>
|
||||
</th>
|
||||
<td>{note.attachmentCount}</td>
|
||||
<td>{formatDate(note.updatedAt)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user