Complete rewrite of bookshelf.templ following PROJECT_GUIDELINES.md:
- Add Alpine.js for UI state management (modals, filters)
- Add HTMX for dynamic filtering without page reload
- Include all filter fields: search, author, series, genre, year, cover
- Add sort dropdown and pagination support
- Add save filter modal for user customizations
- Add clear filters button
- Server-side renders initial page with libraries data
- Use x-show for stateful UI (not class="hidden")
- Prevent FOUC with style="display: none;" on x-show elements
Template now matches SSR-first principles:
- Backend fetches libraries and renders complete HTML
- HTMX swaps book grid on filter changes
- Alpine manages modal visibility and filter state
- No data fetching in x-init (setup only)
Changes to bookshelf_templ.go are auto-generated from .templ file.
- Add bookshelf route with library selection from query param or first available
- Add filter bar UI with library selector, search, and filter controls
- Integrate HTMX for dynamic filtering (hx-get to /api/media-items/filtered)
- Add Alpine.js component for filter state management
- Add filter save/load functionality via /api/bookshelf/filters endpoint
- Update bookshelf.ts to use Alpine.js for reactive state instead of DOM manipulation
Remove redundant <script src="/static/main.js" defer></script> tags from 17+
templates that include the @Header component, eliminating duplicate script
loading that was causing Alpine.js to initialize twice per page load.
The header.templ component now serves as the single source of truth for
main.js inclusion, following the DRY principle and ensuring consistent
script loading across all pages that use the header navigation.
Additionally, add type="button" attribute to all buttons in header navigation
to prevent default form submission behavior when buttons are clicked.
Changes:
- Remove main.js script tag from templates using @Header component
- Keep main.js in header.templ (line 279) as universal inclusion point
- Preserve main.js in special pages: index.templ, login.templ, register.templ
(these don't use @Header and are standalone entry points)
- Add type="button" to theme toggle, theme selection, wood paneling, and user menu buttons
to prevent unwanted form submissions or page navigation
Benefits:
- Eliminates Alpine.js double-initialization bug
- Reduces HTTP requests (one script load instead of two)
- Improves maintainability (add header, get scripts automatically)
- Fixes broken @click handlers on collections, devices, and other pages
- Prevents buttons from triggering default form submission behavior
Technical notes:
- Templates affected: admin, analytics, bookshelf, collection_rules,
collections, conflicts, custom_section, dashboard, devices, docs,
library, profile, progress, queue, unlinked_books
- No changes to entry pages (index, login, register) which don't use @Header
- HTMX script remains in individual templates (stateless, no double-load issue)
- All interactive buttons in header now explicitly marked type="button" to
prevent default browser form submission behavior
Related to: previous commit fixing Vite code-splitting
- Add defer attribute to <script src="/static/main.js"> in 21 template files
- Improves page load performance by allowing HTML parsing to continue without blocking
- Maintains script execution order while enabling parallel resource loading
- Remove duplicate defer attribute from header.templ line 264
- Add websocket.ts import to main.ts for module registration
This optimization reduces page render blocking and improves perceived load times
by allowing the browser to continue parsing HTML while the main.js bundle loads.
The defer attribute ensures scripts execute in order after HTML parsing completes.
Affected templates include:
- Admin pages: admin, admin_library, admin_settings, admin_users
- Content pages: analytics, bookshelf, collections, conflicts, custom_section
- User pages: dashboard, devices, docs, index, login, profile, progress, queue, register
- System pages: header, unlinked_books
- Add defer attribute to all main.js script includes across 22 template files
- Improves page load performance by allowing HTML parsing to continue without blocking
- Maintains script execution order while enabling parallel resource loading
This optimization reduces page render blocking and improves perceived load times
across all admin and user-facing pages that include the main.js bundle.
Affected pages include: admin dashboard, library management, settings, user
management, analytics, bookshelf, collections, conflicts, custom sections,
devices, documentation, profile, progress tracking, queue, and authentication
pages (login/register).
- Remove max-w-7xl containers from all page templates
- Replace with w-full for full-screen width utilization
- Maintain padding for readability
- Admin templates: modify inner content div only (preserve sidebar layout)
- Move header.js script from individual templates to header.templ
- Removes duplicate script tags from bookshelf, collections, progress, etc.
- Fixes indentation in docs.templ
- Add LibraryData type to templates/types.go
- Update bookshelf template to accept libraries parameter
- Render libraries server-side for faster initial page load
- Libraries now populated from server data instead of AJAX fetch
- JavaScript still uses API for dynamic content (bookshelf items)
- Update /bookshelf route to fetch libraries server-side before render
- Properly handle UUID and pgtype.Text conversions
- Maintain API endpoint compatibility for JavaScript calls
This improves initial page load performance while preserving
dynamic functionality via API calls.
Template changes:
- Update page titles: "Bookmann" → "Bookhoard"
- Update header branding and navigation text
- Regenerate compiled .go templates from .templ sources
- Update all UI references in HTML templates
This is part 3 of the project rename to Bookhoard.
- Changed Header component calls from text to proper templ syntax (@Header)
- Header now properly renders navigation, search, theme switcher, and user menu
- Fixed both bookshelf.templ and dashboard.templ templates
- Create bookshelf.templ with beautiful visual bookshelf interface
- Implement wooden shelf appearance with CSS gradients
- Add responsive grid layout (2/3/6 columns based on screen size)
- Books display with 3D spine effect and hover animations
- Auto-select first library and load books on page load
- Empty state and loading state handling
Visual Features:
- Wooden shelves with gradient shadows (12px bottom border)
- Books hover with lift (translateY) and rotation effects
- Book covers with aspect ratio 2/3 and inset spine highlight
- Error handling falls back to placeholder-book.svg
- 6 books per shelf for optimal display
JavaScript Features:
- Fetch visible libraries from API
- Populate library selector dropdown
- Load and display media items on shelves
- Handle empty states gracefully
- Book detail placeholder (to be implemented)