feat(ssr): pass library data to collection page templates

Update frontend route handlers for /collections and /collections/:id
to fetch user-visible libraries and pass libData + currentLibraryID
to templates, enabling the library switcher dropdown.

/collections handler:
- Fetch GetUserVisibleLibraries for the current user
- Derive currentLibraryID from query param, falling back to first library
- Convert to []templates.LibraryData and pass to Collection template

/collections/:id handler:
- Fetch GetUserVisibleLibraries alongside existing book fetching
- Pass libData to CollectionDetail template alongside existing libraryID
- Refactored to use shared libraryID variable across system/user paths
This commit is contained in:
2026-05-17 21:12:13 -04:00
parent faef4d9fff
commit 2fa3764df5
+55 -29
View File
@@ -585,8 +585,32 @@ func registerFrontendRoutes(cfg *Config) {
}
}
userUUID, _ := uuid.Parse(user.ID)
libraries, libErr := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if libErr != nil {
log.Printf("GetUserVisibleLibraries failed: %v", libErr)
libraries = []database.GetUserVisibleLibrariesRow{}
}
currentLibraryID := c.QueryParam("library_id")
if currentLibraryID == "" && len(libraries) > 0 {
libUUID, _ := uuid.FromBytes(libraries[0].ID.Bytes[0:16])
currentLibraryID = libUUID.String()
}
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.Collection(user, colData, errorMsg).Render(c.Request().Context(), &buf)
err = templates.Collection(user, colData, libData, currentLibraryID, errorMsg).Render(c.Request().Context(), &buf)
if err != nil {
return err
}
@@ -674,14 +698,12 @@ func registerFrontendRoutes(cfg *Config) {
userUUID, _ := uuid.Parse(user.ID)
var books []handlers.BookInfo
libraryID := c.QueryParam("library_id")
if collection.QueryType.Valid && collection.QueryType.String != "" {
// System collection - use query type
// System collection - need library_id for system collections
// Get library_id from query param or default to user's first library
libraryID := c.QueryParam("library_id")
if libraryID == "" {
libraries, err := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if err == nil && len(libraries) > 0 {
libraries, libErr := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if libErr == nil && len(libraries) > 0 {
libUUID, _ := uuid.FromBytes(libraries[0].ID.Bytes[0:16])
libraryID = libUUID.String()
}
@@ -689,15 +711,13 @@ func registerFrontendRoutes(cfg *Config) {
libUUID, _ := uuid.Parse(libraryID)
dashboardSvc := services.NewDashboardService(cfg.Queries)
sections, err := dashboardSvc.GetDashboardSections(c.Request().Context(), userUUID, libUUID, 1000, []string{}, []string{})
if err != nil {
sections, secErr := dashboardSvc.GetDashboardSections(c.Request().Context(), userUUID, libUUID, 1000, []string{}, []string{})
if secErr != nil {
return renderErrorPage(c, "Error loading books", "books_load_error")
}
// Find the matching section and convert items
for _, section := range sections {
if section.CollectionID.String() == collectionID {
// Convert []database.MediaItems to []handlers.BookInfo
bookCards := make([]handlers.BookInfo, len(section.Items))
for i, item := range section.Items {
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
@@ -713,27 +733,21 @@ func registerFrontendRoutes(cfg *Config) {
}
}
} else {
// User collection - check if library_id filter is present
libraryID := c.QueryParam("library_id")
if libraryID != "" {
// Filter by library - reuse dashboard query
libUUID, err := uuid.Parse(libraryID)
if err != nil {
libUUID, parseErr := uuid.Parse(libraryID)
if parseErr != nil {
return renderErrorPage(c, "Invalid library ID", "invalid_library_id")
}
// Use GetCollectionItemsForDashboard for library-filtered results
collItems, err := cfg.Queries.GetCollectionItemsForDashboard(c.Request().Context(),
collItems, collErr := cfg.Queries.GetCollectionItemsForDashboard(c.Request().Context(),
database.GetCollectionItemsForDashboardParams{
CollectionID: pgtype.UUID{Bytes: collUUID, Valid: true},
LibraryID: pgtype.UUID{Bytes: libUUID, Valid: true},
Limit: 1000,
})
if err != nil {
if collErr != nil {
books = []handlers.BookInfo{}
} else {
// Convert to BookInfo format (non-excluded only)
var validItems []database.GetCollectionItemsForDashboardRow
for _, item := range collItems {
if !item.Excluded.Valid || !item.Excluded.Bool {
@@ -754,13 +768,11 @@ func registerFrontendRoutes(cfg *Config) {
books = bookCards
}
} else {
// No library filter - show all books in collection
collItems, err := cfg.Queries.GetCollectionItems(c.Request().Context(), pgtype.UUID{Bytes: collUUID, Valid: true})
if err != nil {
collItems, collErr := cfg.Queries.GetCollectionItems(c.Request().Context(), pgtype.UUID{Bytes: collUUID, Valid: true})
if collErr != nil {
books = []handlers.BookInfo{}
}
// Convert to BookInfo format
bookCards := make([]handlers.BookInfo, len(collItems))
for i, item := range collItems {
itemUUID, _ := uuid.FromBytes(item.MediaItemID.Bytes[0:16])
@@ -783,11 +795,25 @@ func registerFrontendRoutes(cfg *Config) {
Icon: collection.Icon.String,
}
// Get library_id from query params for template
libraryID := c.QueryParam("library_id")
// Render the CollectionDetail template
libraries, libErr := cfg.Queries.GetUserVisibleLibraries(c.Request().Context(), uuidToPGType(userUUID))
if libErr != nil {
log.Printf("GetUserVisibleLibraries failed: %v", libErr)
libraries = []database.GetUserVisibleLibrariesRow{}
}
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.CollectionDetail(user, colData, books, libraryID).Render(c.Request().Context(), &buf)
err = templates.CollectionDetail(user, colData, books, libraryID, libData).Render(c.Request().Context(), &buf)
if err != nil {
return err
}