From 670101b61e0c0f9a9ac5e0693b708f906da383f8 Mon Sep 17 00:00:00 2001 From: "Marko (Hermes Implementer)" Date: Fri, 29 May 2026 00:08:32 +0000 Subject: [PATCH] fix: add missing book API methods and types (searchBooks, getBook, getGenres, getAuthors) --- docs/backend/search-discovery-spec.md | 11 ++++++++- frontend/src/api/books.ts | 32 ++++++++++++++++++++++++++- frontend/src/types/book.ts | 20 ++++++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/docs/backend/search-discovery-spec.md b/docs/backend/search-discovery-spec.md index eeff846..590b132 100644 --- a/docs/backend/search-discovery-spec.md +++ b/docs/backend/search-discovery-spec.md @@ -69,7 +69,7 @@ Enable users to search books within the library and discover new books via filte - **Search bar** at top: text input with debounced `onChange` → calls API with `q` param - **Filter row**: genre dropdown, author dropdown, reading status dropdown - Genre/Author dropdowns populated from `/api/books/genres/` and `/api/books/authors/` - - Reading status uses static enum values + - Reading status uses static enum values (`READING_STATUS_OPTIONS`) - **Results grid**: card layout showing cover, title, author, reading status badge - **Empty state**: "No books found" with clear message when results are empty - **Loading state**: spinner/skeleton while fetching @@ -80,6 +80,15 @@ Enable users to search books within the library and discover new books via filte - Back button to return to library - Clean, mobile-responsive layout +### API Client — `frontend/src/api/books.ts` + +| Method | Endpoint | Returns | +|--------|----------|---------| +| `searchBooks(params)` | `GET /api/books/` | `{count, results: BookListItem[]}` | +| `getBook(id)` | `GET /api/books/{id}/` | `BookDetail` | +| `getGenres()` | `GET /api/books/genres/` | `string[]` | +| `getAuthors()` | `GET /api/books/authors/` | `string[]` | + ## Routes (Frontend) | Path | Component | Auth | |------|-----------|------| diff --git a/frontend/src/api/books.ts b/frontend/src/api/books.ts index 5d65379..029f46d 100644 --- a/frontend/src/api/books.ts +++ b/frontend/src/api/books.ts @@ -1,5 +1,15 @@ import api from "./client"; -import type { ContentResponse, EBookDetail, EBookListItem, ReadingProgress, ReadingSettings, TocResponse } from "../types/book"; +import type { + BookDetail, + BookListItem, + BookSearchParams, + ContentResponse, + EBookDetail, + EBookListItem, + ReadingProgress, + ReadingSettings, + TocResponse, +} from "../types/book"; export const booksApi = { async getEBooks(): Promise { @@ -12,6 +22,26 @@ export const booksApi = { return data; }, + async searchBooks(params: BookSearchParams = {}): Promise<{ count: number; results: BookListItem[] }> { + const { data } = await api.get<{ count: number; results: BookListItem[] }>("/books/", { params }); + return data; + }, + + async getBook(id: number): Promise { + const { data } = await api.get(`/books/${id}/`); + return data; + }, + + async getGenres(): Promise { + const { data } = await api.get("/books/genres/"); + return data; + }, + + async getAuthors(): Promise { + const { data } = await api.get("/books/authors/"); + return data; + }, + async uploadEBook( file: File, title: string, diff --git a/frontend/src/types/book.ts b/frontend/src/types/book.ts index b81a169..c45ef41 100644 --- a/frontend/src/types/book.ts +++ b/frontend/src/types/book.ts @@ -81,4 +81,22 @@ export interface ContentResponse { content: string; chapter_title: string; format: string; -} \ No newline at end of file +} + +export interface BookSearchParams { + q?: string; + genre?: string; + author?: string; + reading_status?: string; + ordering?: string; + page?: number; + page_size?: number; +} + +export const READING_STATUS_OPTIONS: { value: string; label: string }[] = [ + { value: "", label: "All Statuses" }, + { value: "want_to_read", label: "Want to Read" }, + { value: "reading", label: "Reading" }, + { value: "finished", label: "Finished" }, + { value: "dnf", label: "Did Not Finish" }, +]; \ No newline at end of file