Some serious layout changes

This commit is contained in:
Simon Martens
2025-09-27 23:30:37 +02:00
parent 31b4be14ae
commit c92d25752c
24 changed files with 1832 additions and 1796 deletions

View File

@@ -140,12 +140,80 @@ func GetQuickFilter(kgpz *xmlmodels.Library) fiber.Handler {
return strings.Compare(a.ID, b.ID)
})
// Get all categories with their first available year
categories := make([]CategorySummary, 0)
categoryYears := make(map[string][]int) // categoryID -> list of years
// First pass: collect all years for each category
for _, piece := range kgpz.Pieces.Array {
// Get years for this piece
pieceYears := make(map[int]bool)
for _, issueRef := range piece.IssueRefs {
if issueRef.When.Year > 0 {
pieceYears[issueRef.When.Year] = true
}
}
// Process CategoryRefs
for _, catRef := range piece.CategoryRefs {
if catRef.Ref != "" {
for year := range pieceYears {
categoryYears[catRef.Ref] = append(categoryYears[catRef.Ref], year)
}
}
}
// Process WorkRefs with categories (rezension)
for _, workRef := range piece.WorkRefs {
categoryID := workRef.Category
if categoryID == "" {
categoryID = "rezension" // Default category for WorkRefs
}
for year := range pieceYears {
categoryYears[categoryID] = append(categoryYears[categoryID], year)
}
}
}
// Build categories list with first year for each
kgpz.Categories.Lock()
for _, category := range kgpz.Categories.Array {
if yearsList, exists := categoryYears[category.ID]; exists && len(yearsList) > 0 {
// Find the earliest year for this category
slices.Sort(yearsList)
firstYear := yearsList[0]
// Get the primary name (first name in the list)
var name string
if len(category.Names) > 0 {
name = category.Names[0]
} else {
name = category.ID // fallback to ID if no names
}
categorySummary := CategorySummary{
ID: category.ID,
Name: name,
FirstYear: firstYear,
}
categories = append(categories, categorySummary)
}
}
kgpz.Categories.Unlock()
// Sort categories list by name
slices.SortFunc(categories, func(a, b CategorySummary) int {
return strings.Compare(a.Name, b.Name)
})
// Prepare data for the filter template
data := fiber.Map{
"AvailableYears": availableYears,
"Persons": persons,
"Authors": authors,
"Places": places,
"Categories": categories,
"IssuesByYearJSON": string(issuesByYearJSON),
}
@@ -168,6 +236,13 @@ type PlaceSummary struct {
Geo string
}
// CategorySummary represents a simplified category for the filter list
type CategorySummary struct {
ID string
Name string
FirstYear int
}
// IssueSummary represents an issue for the Jahr/Ausgabe filter
type IssueSummary struct {
Number int `json:"number"`

View File

@@ -1,12 +1,111 @@
package controllers
import (
"slices"
"strconv"
"strings"
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
"github.com/Theodor-Springmann-Stiftung/kgpz_web/viewmodels"
"github.com/Theodor-Springmann-Stiftung/kgpz_web/xmlmodels"
"github.com/gofiber/fiber/v2"
)
const (
DEFAULT_CATEGORY = ""
)
func GetCategory(kgpz *xmlmodels.Library) fiber.Handler {
return func(c *fiber.Ctx) error {
return c.Render("/kategorie/", nil)
categoryID := c.Params("category", DEFAULT_CATEGORY)
categoryID = strings.ToLower(categoryID)
yearParam := c.Params("year", "")
// Case 1: No category specified - show categories list with years
if categoryID == "" {
categories := viewmodels.CategoriesView(kgpz)
if len(categories.Categories) == 0 {
logging.Error(nil, "No categories found")
return c.SendStatus(fiber.StatusNotFound)
}
return c.Render("/kategorie/list/", fiber.Map{
"model": categories,
})
}
// Case 2: Both category and year specified - show pieces
if yearParam != "" {
year, err := strconv.Atoi(yearParam)
if err != nil {
logging.Error(err, "Invalid year parameter: "+yearParam)
return c.SendStatus(fiber.StatusBadRequest)
}
categoryPieces := viewmodels.NewCategoryPiecesView(categoryID, year, kgpz)
if categoryPieces == nil {
logging.Error(nil, "Category not found: "+categoryID)
return c.SendStatus(fiber.StatusNotFound)
}
return c.Render("/kategorie/pieces/", fiber.Map{
"model": categoryPieces,
})
}
// Case 3: Category specified but no year - find first available year and redirect
firstYear := findFirstYearForCategory(categoryID, kgpz)
if firstYear == 0 {
// Category exists but has no pieces, redirect to category list
logging.Error(nil, "Category has no pieces: "+categoryID)
return c.Redirect("/kategorie/")
}
// Redirect to category with first available year
return c.Redirect("/kategorie/" + categoryID + "/" + strconv.Itoa(firstYear))
}
}
// findFirstYearForCategory finds the earliest year that has pieces for the given category
func findFirstYearForCategory(categoryID string, kgpz *xmlmodels.Library) int {
categoryYears := make([]int, 0)
for _, piece := range kgpz.Pieces.Array {
matchesCategory := false
// Check direct CategoryRefs
for _, catRef := range piece.CategoryRefs {
if catRef.Ref == categoryID {
matchesCategory = true
break
}
}
// Check WorkRefs with categories if not found in direct refs
if !matchesCategory {
for _, workRef := range piece.WorkRefs {
if workRef.Category == categoryID || (workRef.Category == "" && categoryID == "rezension") {
matchesCategory = true
break
}
}
}
if matchesCategory {
// Extract years from IssueRefs
for _, issueRef := range piece.IssueRefs {
year := issueRef.When.Year
if year > 0 {
categoryYears = append(categoryYears, year)
}
}
}
}
if len(categoryYears) == 0 {
return 0 // No pieces found for this category
}
// Find the earliest year
slices.Sort(categoryYears)
return categoryYears[0]
}