feat: add template helper functions for book detail page
Add utility functions for rendering book metadata: - renderStars(): Convert rating (1-10 scale) to star display - formatFileSize(): Convert bytes to human-readable format (KB, MB, GB) - getExternalURL(): Generate URLs for external book services with smart fallback: ID → ISBN → Title+Author search Supports Goodreads, Open Library, Google Books, Amazon These helpers make book detail template cleaner and follow DRY principle.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
@@ -32,3 +34,91 @@ func uuidToString(id pgtype.UUID) string {
|
||||
}
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// renderStars converts rating (1-10 scale) to star display
|
||||
// Rating scale: 1-10 where odd numbers = half stars (1=0.5★, 3=1.5★, etc.)
|
||||
func renderStars(rating int32) string {
|
||||
stars := ""
|
||||
fullStars := rating / 2
|
||||
hasHalf := rating%2 != 0
|
||||
|
||||
for i := int32(0); i < fullStars; i++ {
|
||||
stars += "★"
|
||||
}
|
||||
if hasHalf {
|
||||
stars += "½"
|
||||
}
|
||||
|
||||
return stars
|
||||
}
|
||||
|
||||
// formatFileSize converts bytes to human-readable format
|
||||
func formatFileSize(bytes int64) string {
|
||||
const (
|
||||
KB = 1024
|
||||
MB = KB * 1024
|
||||
GB = MB * 1024
|
||||
)
|
||||
|
||||
switch {
|
||||
case bytes >= GB:
|
||||
return fmt.Sprintf("%.2f GB", float64(bytes)/float64(GB))
|
||||
case bytes >= MB:
|
||||
return fmt.Sprintf("%.2f MB", float64(bytes)/float64(MB))
|
||||
case bytes >= KB:
|
||||
return fmt.Sprintf("%.2f KB", float64(bytes)/float64(KB))
|
||||
default:
|
||||
return fmt.Sprintf("%d B", bytes)
|
||||
}
|
||||
}
|
||||
|
||||
// getExternalURL generates URL for external book services
|
||||
// Priority: ID > ISBN > Title+Author search
|
||||
func getExternalURL(service string, id string, isbn pgtype.Text, title string, author pgtype.Text) string {
|
||||
baseURL := ""
|
||||
searchTerm := ""
|
||||
|
||||
// Determine search term: ID > ISBN > Title+Author
|
||||
if id != "" {
|
||||
searchTerm = id
|
||||
} else if isbn.Valid && isbn.String != "" {
|
||||
searchTerm = isbn.String
|
||||
} else {
|
||||
// Build title+author search query
|
||||
if author.Valid && author.String != "" {
|
||||
searchTerm = fmt.Sprintf("%s %s", title, author.String)
|
||||
} else {
|
||||
searchTerm = title
|
||||
}
|
||||
}
|
||||
|
||||
// Build URL based on service
|
||||
switch service {
|
||||
case "goodreads":
|
||||
if id != "" {
|
||||
baseURL = "https://www.goodreads.com/book/show/"
|
||||
} else {
|
||||
baseURL = "https://www.goodreads.com/search?q="
|
||||
}
|
||||
case "openlibrary":
|
||||
if id != "" {
|
||||
baseURL = "https://openlibrary.org/books/"
|
||||
} else {
|
||||
baseURL = "https://openlibrary.org/search?q="
|
||||
}
|
||||
case "googlebooks":
|
||||
if id != "" {
|
||||
baseURL = "https://books.google.com/books?id="
|
||||
} else {
|
||||
baseURL = "https://www.google.com/search?tbm=bks&q="
|
||||
}
|
||||
case "amazon":
|
||||
// Amazon doesn't have direct book IDs, always search
|
||||
baseURL = "https://www.amazon.com/s?k="
|
||||
if isbn.Valid && isbn.String != "" {
|
||||
searchTerm = isbn.String
|
||||
}
|
||||
}
|
||||
|
||||
return baseURL + searchTerm
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user