Commit Graph
10 Commits
Author SHA1 Message Date
john-okeefe a075a5061f feat(ui): refresh auth, entry, admin, and secondary pages
Apply the new design-system primitives across the remaining pages so the
whole app shares one visual language:

- Auth/entry: redesigned index, login, register (centered card layout,
  SVG icons, semantic tokens)
- Admin: sidebar nav with icons, cohesive admin dashboard/users/library/
  processing-issues/settings (tables use border-line + hover states;
  scan/websocket attributes preserved)
- Secondary: analytics (stat cards), devices, progress, conflicts, queue,
  profile + form/modal all migrated to .card/.btn/.input primitives and
  SVG action icons
- Docs + API explorer + setup wizard + collection/rules/modals +
  unlinked books + book-detail modals: consistent chrome, modal scrims
  use --surface-overlay, close buttons use icon-btn
- reader.templ and error.templ intentionally left unchanged
2026-08-05 16:01:22 -04:00
john-okeefe ce3ab8bcbc Fix invalid templ conditional syntax in metadata editor modal
The Manga Type and Reading Direction select options used invalid inline
if syntax: 'if cond { selected }' which is not valid templ. Replaced
with the correct templ attribute syntax: selected={ boolExpression }
which properly renders the selected attribute when true and omits it
when false.

Also add for/id attributes to link labels to their select elements
for accessibility (manga_type and reading_direction).

Affected lines: book_detail_modals.templ:478-496
2026-06-08 21:19:06 -04:00
john-okeefe bc59159cde feat(ui): inline conflict resolution with Keep This button
Replace the 'Go to Conflicts Page' link with inline conflict resolution.
Each conflict source now has a 'Keep This' button that resolves the
conflict directly from the book detail page.

- Conflict data now keyed by source name (koreader, web) instead of
  new/existing, with Source and Timestamp fields
- Display percentage scaled correctly (* 100)
- Fix page field name from current_page to page
- Add conflict resolution JavaScript in book-detail.ts
- Add 10-minute cooldown after resolution to prevent re-detection
2026-06-02 19:46:17 -04:00
john-okeefe 504f145f64 feat(metadata-editor): replace tags text input with badge picker + autocomplete
Replace the comma-separated text input for tags in the metadata editor
with a badge-based tag picker:
- Current tags shown as removable pill badges (✕ button per tag)
- Autocomplete input queries existing tags via shared tag-dropdown module
- Results shown as inline dropdown (not absolute, avoids overflow clipping
  from the modal's overflow-y-auto content area)
- Keyboard navigation: ArrowUp/Down, Enter to select, comma to add new,
  Escape to close
- Supports adding new tags not in the database (type + Enter/comma)
- Hidden data-editor-tag spans seed initial tags from server-side render
- collectFormData() now accepts editorTags array, skips the removed
  tags text input
2026-05-10 16:13:07 -04:00
john-okeefe 4f2e1e36bf feat(templates): add metadata editor modal with cover management
New MetadataEditorModal component with:
- Cover section (w-64 h-96, matching book detail page layout): click-to-upload,
  Generate Cover button, Remove Cover button
- Accordion sections: Basic Info, Publication, Series, Identifiers,
  Comic/Manga, Technical — covering all 34 editable metadata fields
- Modal capped at 90vh with scrollable content area
- Cover upload via hidden file input with hover overlay
- Select dropdowns for MangaType and ReadingDirection
- Read-only display for Format and File Size
2026-05-10 11:52:53 -04:00
john-okeefe 5da91b9c7c feat(ui): use timezone-aware time formatting across all templates
Replace hardcoded .Format() calls with FormatInTimezone() and
FormatTimestamptzInTimezone() helpers so all timestamps display in
the user's selected timezone.

Changes:
- book_detail.templ: remove incorrect templates. package prefix
- book_detail_modals.templ: add User param to ProgressSyncModal so
  timezone is available; convert Timestamp to FormatInTimezone()
- devices.templ: convert LastSync and LastSeen to FormatInTimezone()
- conflicts.templ: convert CreatedAt to FormatInTimezone()
- admin_users.templ: convert CreatedAt to FormatInTimezone() using
  currentUser.Timezone

Note: DatePublished is kept as a plain date format (MM-DD-YYYY) since
it is a pgtype.Date, not a timestamp, and does not need timezone
conversion.
2026-04-29 20:32:51 -04:00
john-okeefe 55a9ec00e1 fix(ui): use timezone-aware formatting for Last Read timestamps in book detail and progress sync modal
Replace hardcoded 12-hour Format() calls with FormatTimestamptzInTimezone()
so that the Last Read time respects the user's selected timezone preference.
Both book_detail.templ and book_detail_modals.templ now use the same
timezone-aware helper that was introduced in the timezone support feature.
2026-04-28 21:12:01 -04:00
john-okeefe e5726e12be Switch all user-facing time displays to 12-hour MM-DD-YYYY format
Consistently format dates and times across all templates and API
handlers using MM-DD-YYYY with 12-hour clock (03:04 PM):

- analytics.go: date keys, lastSync, lastRead timestamps
- progress.go: lastUpdated timestamp in GetAllProgress
- book_detail.templ: LastReadAt, DatePublished
- book_detail_modals.templ: progress sync timestamps, LastReadAt
- devices.templ: LastSync, LastSeen
- conflicts.templ: CreatedAt
- admin_users.templ: user CreatedAt date
2026-04-27 21:31:19 -04:00
john-okeefe d38804e910 fix(progress): correct percentage display and add format-aware progress
Fix two bugs in progress display across book detail, progress page, reader,
and sync modal templates:

1. Percentage was stored as 0.0-1.0 fraction but displayed as-if 0-100
   (showing 0.5% instead of 50%). Multiply by 100 at the data source in
   both GetAllProgress and GetAllProgressData handlers, and in the reader
   route's ReadingProgress construction.

2. Progress bar width was never evaluated — { expr } inside style=".."
   was rendered as literal text by templ, resulting in 0% width bars for
   all items. Fixed by using templ's style={ expr } attribute syntax
   which evaluates the Go expression (uses SanitizeStyleAttributeValues).

Also add format-aware progress display:
- Reader template: shows "45% · Page 89/196" for reflowable (estimated
  pages), "127/342" for comics/PDFs (actual pages)
- Progress page: shows "Page X of Y (est.)" for reflowable, "X / Y"
  for fixed layout
- Add FormatGroup and EstimatedPages to ProgressWithMedia struct
- Remove hardcoded totalPages=200 fallback in progress handler (now 0)
- Add fmt import to progress.templ for string formatting
2026-04-24 14:03:03 -04:00
john-okeefe eb349cbc95 feat: add book detail page with comprehensive metadata display
Implement SSR-first book detail page at /media/:uuid with complete
book information, progress tracking, and interactivity.

Features:
- Cover image (256x384px) with responsive layout
- Complete metadata: title, author, description, publisher, ISBN,
  language, edition, page count, genre, copyright year, format
- External service links (Goodreads, Open Library, Google Books, Amazon)
  with smart URL fallback: ID → ISBN → Title+Author
- Reading progress display with device sources (web/kobo/koreader)
- Sync progress modal for conflict resolution
- Collections display as clickable badges
- Notes/highlights counter with placeholder modal
- Rating display (1-10 scale with star rendering)
- HTML sanitization for book descriptions using bluemonday

Data Structure:
- handlers.MediaDetail embeds database.MediaItems for zero duplication
- Uses existing database queries (GetMediaItem, GetMediaRating, etc.)
- Follows project pattern: no parallel type systems

Frontend:
- TypeScript modal triggers (book-detail.ts)
- Alpine.js for modal interactions
- TailwindCSS styling with theme variables
- Responsive: cover-left layout, mobile stacks vertically

Backend:
- Route: GET /media/:uuid (protected)
- Handler: inline function in frontend.go following existing pattern
- Template: SSR-first with progressive enhancement
- Returns HTML only (API uses separate /api/media-items/:id endpoint)

Files created:
- internal/handlers/media_detail.go
- templates/book_detail.templ
- templates/book_detail_modals.templ
- web/src/book-detail.ts

Files modified:
- internal/router/frontend.go (add route)
- web/src/main.ts (import module)
2026-03-28 23:54:39 -04:00