feat: restore bookshelf page route and add navigation link

- Add /bookshelf route in frontend.go (was typo /booskshelf)
- Route fetches libraries server-side and renders complete HTML
- Supports library_id query param or defaults to user's first library
- Add "All Books" link to header navigation
- Follows SSR-first architecture principles

Fixes route registration that prevented bookshelf page from loading.
This commit is contained in:
2026-03-20 11:43:17 -04:00
parent f2cbb5a433
commit 513ff7c82f
3 changed files with 60 additions and 2 deletions
+51
View File
@@ -117,6 +117,57 @@ func registerFrontendRoutes(cfg *Config) {
return ""
}
frontendProtected.GET("/bookshelf", func(c *echo.Context) error {
user, err := getTemplateUserWithTheme(c, cfg)
if err != nil {
return renderErrorPage(c, "Error loading user", "user_load_error")
}
var errorMsg string
// Get library_id from query param or user's first library
libraryID := c.QueryParam("library_id")
if libraryID == "" {
userUUID, _ := uuid.Parse(user.ID)
libraries, err := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if err == nil && len(libraries) > 0 {
libUUID, _ := uuid.FromBytes(libraries[0].ID.Bytes[0:16])
libraryID = libUUID.String()
} else {
errorMsg = "No libraries available"
}
}
// Get libraries for dropdown
userUUID, _ := uuid.Parse(user.ID)
libraries, err := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if err != nil {
log.Printf("GetUserVisibleLibraries failed: %v", err)
libraries = []database.GetUserVisibleLibrariesRow{}
if errorMsg == "" {
errorMsg = "Error loading libraries"
}
}
libData := make([]templates.LibraryData, len(libraries))
for i, lib := range libraries {
libUUID, _ := uuid.FromBytes(lib.ID.Bytes[0:16])
libData[i] = templates.LibraryData{
ID: libUUID.String(),
Name: lib.Name,
Description: getText(lib.Description),
TypeName: lib.TypeName,
}
}
var buf bytes.Buffer
err = templates.BookShelf(user, libData, libraryID, errorMsg).Render(c.Request().Context(), &buf)
if err != nil {
return err
}
return c.HTML(http.StatusOK, buf.String())
})
// Dashboard page
frontendProtected.GET("/dashboard", func(c *echo.Context) error {
user, err := getTemplateUserWithTheme(c, cfg)
+7
View File
@@ -14,6 +14,13 @@ templ Header(user User, currentPath string) {
<a href="/dashboard" class="text-sm hover:opacity-80 transition-opacity" style="color: var(--text-secondary); text-decoration: none;">
Library
</a>
<a
href="/bookshelf"
class="text-sm hover:opacity-80 transition-opacity"
style="color: var(--text-secondary); text-decoration: none;"
>
All Books
</a>
<a href="/collections" class="text-sm hover:opacity-80 transition-opacity" style="color: var(--text-secondary); text-decoration: none;">
Collections
</a>
File diff suppressed because one or more lines are too long