-
- Huaqo's Wunschzettel
-
-
-
-
+
+
+
+
+ Huaqo's Wunschzettel
+ {{ books.length === total ? total : `${books.length} / ${total}` }}
+
+
+ Überrasch mich gern auch mit etwas, das hier nicht zu finden ist <3
+
+
+
+
@@ -34,7 +45,7 @@ const { books, total, error, status } = useWishlist(search, sort)
color="error"
variant="subtle"
icon="i-lucide-triangle-alert"
- title="Couldn't load the wishlist"
+ title="Der Wunschzettel konnte nicht geladen werden"
:description="(error.data as { statusMessage?: string } | undefined)?.statusMessage || error.statusMessage || error.message"
class="mb-6"
/>
@@ -43,9 +54,24 @@ const { books, total, error, status } = useWishlist(search, sort)
-
- {{ search ? 'No book matches your search.' : 'The wishlist is empty.' }}
+
+ {{ search ? 'Kein Buch passt zu deiner Suche.' : 'Der Wunschzettel ist leer.' }}
+
+
+
+
+
+
+
+
diff --git a/layers/wishlist/server/api/wishlist/read.get.ts b/layers/wishlist/server/api/wishlist/read.get.ts
new file mode 100644
index 0000000..1b2df58
--- /dev/null
+++ b/layers/wishlist/server/api/wishlist/read.get.ts
@@ -0,0 +1 @@
+export default defineEventHandler(event => listShelfBooks(event, { filter__read__boolean: true }))
diff --git a/layers/wishlist/server/api/wishlist/reading.get.ts b/layers/wishlist/server/api/wishlist/reading.get.ts
new file mode 100644
index 0000000..cdcfc38
--- /dev/null
+++ b/layers/wishlist/server/api/wishlist/reading.get.ts
@@ -0,0 +1 @@
+export default defineEventHandler(event => listShelfBooks(event, { filter__currently_reading__boolean: true }))
diff --git a/layers/wishlist/server/utils/shelf.ts b/layers/wishlist/server/utils/shelf.ts
new file mode 100644
index 0000000..0ab03bc
--- /dev/null
+++ b/layers/wishlist/server/utils/shelf.ts
@@ -0,0 +1,46 @@
+import type { H3Event } from 'h3'
+
+interface LinkValue {
+ value: string | null
+}
+
+export interface ShelfBookRow {
+ id: number
+ title: string | null
+ title_german: string | null
+ authors: LinkValue[]
+}
+
+interface Field {
+ name: string
+ link_row_table_id?: number
+}
+
+let booksTable: string | null = null
+
+/** The books table, taken from the wishlist table's `books` link field. */
+export async function wishlistBooksTable(event: H3Event): Promise
{
+ if (!booksTable) {
+ const fields = await listFields(event, wishlistTable(event))
+ const id = fields.find(field => field.name === 'books')?.link_row_table_id
+ if (!id) {
+ throw createError({ statusCode: 500, statusMessage: 'The wishlist table has no "books" link field' })
+ }
+ booksTable = String(id)
+ }
+ return booksTable
+}
+
+export function toShelfBook(row: ShelfBookRow): WishlistShelfBook {
+ return {
+ id: row.id,
+ title: row.title_german?.trim() || (row.title ?? '').trim(),
+ authors: (row.authors ?? []).map(({ value }) => value?.trim()).filter((value): value is string => !!value)
+ }
+}
+
+/** Books from the books table matching a Baserow filter, e.g. `{ filter__read__boolean: true }` */
+export async function listShelfBooks(event: H3Event, filters: Record): Promise {
+ const rows = await listRows(event, await wishlistBooksTable(event), filters)
+ return rows.map(toShelfBook).filter(book => book.title)
+}
diff --git a/layers/wishlist/shared/types/wishlist.ts b/layers/wishlist/shared/types/wishlist.ts
index ab457a9..c88a3d8 100644
--- a/layers/wishlist/shared/types/wishlist.ts
+++ b/layers/wishlist/shared/types/wishlist.ts
@@ -8,3 +8,10 @@ export interface WishlistBook {
/** As stored in Baserow: "Last, First" */
authors: string[]
}
+
+/** A book from the books table, as listed under "Gerade am Lesen" and "Bereits gelesen" */
+export interface WishlistShelfBook {
+ id: number
+ title: string
+ authors: string[]
+}
diff --git a/server/utils/baserow.ts b/server/utils/baserow.ts
index 3a377f7..4662154 100644
--- a/server/utils/baserow.ts
+++ b/server/utils/baserow.ts
@@ -38,12 +38,13 @@ async function request(
}
}
-export async function listRows(event: H3Event, tableId: string): Promise {
+/** All rows of a table. `filters` are Baserow row filters, e.g. `{ filter__read__boolean: true }`. */
+export async function listRows(event: H3Event, tableId: string, filters: Fields = {}): Promise {
const path = `rows/table/${tableId}/`
const rows: Row[] = []
for (let page = 1; ; page++) {
const { count, results } = await request>(event, path, {
- query: { user_field_names: true, size: PAGE_SIZE, page }
+ query: { ...filters, user_field_names: true, size: PAGE_SIZE, page }
})
rows.push(...results)
if (rows.length >= count || results.length === 0) return rows