diff --git a/BOOK_DETAIL_IMPLEMENTATION.md b/BOOK_DETAIL_IMPLEMENTATION.md deleted file mode 100644 index d25bc99..0000000 --- a/BOOK_DETAIL_IMPLEMENTATION.md +++ /dev/null @@ -1,1076 +0,0 @@ -# Book Detail Page Implementation Guide - -Complete implementation guide for the `/media/:uuid` book detail page. - -## ✅ Verified Backend Code - -All database queries, function signatures, and struct definitions used in this guide have been verified against the actual codebase: - -- `GetMediaItem` ✓ (line 179 in querier.go) -- `GetMediaRating` ✓ (line 201 in querier.go) -- `GetCollectionsForBook` ✓ (line 132 in querier.go) -- `GetReadingProgress` ✓ (line 213 in querier.go) -- `ListSyncConflictsByMediaItem` ✓ (line 267 in querier.go) -- `GetMediaNotes` ✓ (line 200 in querier.go) -- `GetMediaHighlights` ✓ (line 178 in querier.go) -- `database.MediaItems` struct ✓ (lines 182-235 in models.go) -- `database.Collections` struct ✓ (lines 20-34 in models.go) -- `database.MediaRatings` struct ✓ (lines 254-262 in models.go) -- `database.ReadingProgress` struct ✓ (lines 287-312 in models.go) - -## Overview - -- **Route**: `GET /media/:uuid` -- **Template**: SSR-first with Alpine.js for modal interactions -- **Data Structure**: Embeds `database.MediaItems` to avoid duplication -- **Features**: Cover + metadata, progress tracking, sync modal, collections, placeholder buttons - ---- - -## Files to Create - -### 1. MediaDetail Data Structure - -**Location**: `internal/handlers/media_detail.go` (new file) - -**Full file content**: - -```go -package handlers - -import ( - "bookhoard/internal/database" - "encoding/json" - - "github.com/google/uuid" - "github.com/jackc/pgx/v5/pgtype" -) - -// MediaDetail embeds database.MediaItems for complete book metadata -// No field duplication - template gets direct access to all database fields -type MediaDetail struct { - database.MediaItems // Embedded - ALL book fields available - - // User-specific data - Rating *database.MediaRatings `json:"rating,omitempty"` - Collections []database.Collections `json:"collections"` - ReadingProgress *database.ReadingProgress `json:"reading_progress,omitempty"` - - // Conflict data (if exists) - ActiveConflict *ConflictDetailResponse `json:"active_conflict,omitempty"` - - // Computed counts - NotesCount int `json:"notes_count"` - HighlightsCount int `json:"highlights_count"} -} -``` - -**Note**: The actual handler is implemented in `internal/router/frontend.go` as an inline function (see step 5), following the pattern used by all other frontend routes in this codebase. - ---- - -### 2. `templates/book_detail.templ` - -**Location**: `templates/book_detail.templ` (new file) - -**Full file content**: - -```templ -package templates - -import "bookhoard/internal/handlers" - -templ BookDetail(user User, book handlers.MediaDetail, errorMessage string) { - - -
- - -{ book.Description.String }
-- ⚠️ Progress conflict detected - Click "Sync Progress" to review and resolve -
-Progress
-- { fmt.Sprintf("%.1f", book.ReadingProgress.Percentage.Float64) }% -
-Page
-{ book.ReadingProgress.CurrentPage.Int32 } / { book.ReadingProgress.TotalPages.Int32 }
-Last Read
-{ book.ReadingProgress.LastReadAt.Time.Format("2006-01-02 15:04") }
-Source
-{ book.ReadingProgress.LastSyncSource.String }
-Publisher
-{ book.Publisher.String }
-Published
-{ book.DatePublished.Time.Format("2006-01-02") }
-ISBN
-{ book.ISBN.String }
-Language
-{ book.Language.String }
-Edition
-{ book.Edition.String }
-Pages
-{ book.PageCount.Int32 }
-Genre
-{ book.Genre.String }
-Copyright Year
-{ book.CopyrightYear.Int32 }
-Format
-{ book.MimeType.String }
-File Size
-{ formatFileSize(book.FileSize.Int64) }
-{ book.Title }
-- ⚠️ Conflict Detected -
-- Progress differs between devices. Review the options below and manually resolve via the Conflicts page. -
- - Go to Conflicts Page → - -- { data.Timestamp.Format("2006-01-02 15:04:05") } -
-No conflicts detected. Current progress from { book.ReadingProgress.LastSyncSource.String }:
-- { book.ReadingProgress.LastSyncSource.String } -
- if book.ReadingProgress.CurrentPage.Valid && book.ReadingProgress.TotalPages.Valid { -- Page { book.ReadingProgress.CurrentPage.Int32 } of { book.ReadingProgress.TotalPages.Int32 } -
- } - if book.ReadingProgress.LastReadAt.Valid { -- Last read: { book.ReadingProgress.LastReadAt.Time.Format("2006-01-02 15:04") } -
- } -- This book has { book.NotesCount } notes and { book.HighlightsCount } highlights. -
-Feature coming soon!
-