This repository has been archived on 2026-07-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cloud-reader/docs/frontend/component-spec.md
T
Marko (Hermes Implementer) 84d8fed3f2 feat: full book management system with backend API, frontend UI, and spec docs
- Backend: Book model with reading progress, DRF ViewSet with full CRUD,
  search, sort, filter, pagination, mark-as-finished, stats endpoint
- Frontend: Library grid, BookCard, BookDetail, BookForm components with
  React 19 + TypeScript + Vite
- Tests: 29 passing tests covering models, API, serializers, permissions
- Spec: backend api-spec.md and frontend component-spec.md in docs/

Closes crisleo-hermes/cloud-reader#3
2026-05-26 04:35:13 +00:00

82 lines
3.2 KiB
Markdown

# Frontend Component Specification — Cloud Reader
## Overview
React 19 + TypeScript SPA using Vite for development and production builds. State managed via React hooks and Context API. Routing via `react-router-dom` v7 with `lazy`/`Suspense` for code splitting.
## Components
### App (root)
- **Path:** `/`
- **Layout:** Header with logo + `<Routes>` wrapper
- **Routing:** `/``Library`, `*` → redirect to `/`
- **Code splitting:** `Library` loaded via `React.lazy` + `<Suspense>`
### Library
- **State:** `books[]`, `stats`, `search`, `sortBy`, `statusFilter`, `currentPage`, `view`
- **Views:** `library` (grid), `detail` (selected book), `add` (modal form)
- **Sub-components:** `BookCard`, `BookDetail`, `BookForm`
- **Data flow:** Calls `fetchBooks()` on mount and when filters/page change
### BookCard
- **Props:** `{ book: Book, onClick: (book: Book) => void }`
- **Display:** Cover image (or first-letter placeholder), title, author, genre badge, reading progress bar with status color
- **Interaction:** Click/keyboard-accessible (Enter/Space)
### BookDetail
- **Props:** `{ bookId: number, onBack: () => void, onUpdated: () => void }`
- **Sections:** Cover, metadata (title, author, genre, ISBN), progress bar with page count, action buttons
- **Actions:** Mark as Finished, Edit Details (switches to BookForm), Delete (with confirmation)
- **States:** Loading, error, editing mode
### BookForm
- **Props:** `{ initialData?: Book, onSubmit: (data: BookFormData) => Promise<void>, onCancel: () => void }`
- **Fields:** Title*, Author*, Genre, Description, Cover URL, ISBN, Total Pages, Current Page, Status
- **Client validation:** Title/author required, page ≤ total pages
- **Loading state:** Submit button shows "Saving..." when `isLoading`
## Types
```typescript
interface Book {
id: number; title: string; author: string; genre: string;
description: string; cover_image_url: string; isbn: string;
total_pages: number; current_page: number;
reading_status: ReadingStatus; reading_progress: number;
owner: string; created_at: string; updated_at: string;
}
type ReadingStatus = 'not_started' | 'reading' | 'finished' | 'dnf';
interface BookFormData {
title: string; author: string; genre: string;
description: string; cover_image_url: string; isbn: string;
total_pages: number; current_page: number; reading_status: ReadingStatus;
}
```
## API Client (`api/books.ts`)
| Function | HTTP Call |
|----------------------|------------------------------------|
| `fetchBooks(params)` | `GET /api/books/` |
| `fetchBook(id)` | `GET /api/books/{id}/` |
| `createBook(data)` | `POST /api/books/` |
| `updateBook(id, data)` | `PATCH /api/books/{id}/` |
| `deleteBook(id)` | `DELETE /api/books/{id}/` |
| `markAsFinished(id)` | `POST /api/books/{id}/mark_finished/` |
| `fetchBookStats()` | `GET /api/books/stats/` |
## Styling
Dark theme with CSS custom properties. All styles in `App.css`. Responsive grid layout with breakpoint at 768px.
## Build & Dev
- `yarn workspace frontend dev` — Vite dev server on port 5173 with API proxy to 127.0.0.1:8000
- `yarn workspace frontend build` — TypeScript check + Vite production build