package templates import "fmt" // HashConflictItemData is one copy in a conflict group. type HashConflictItemData struct { ID string Title string Author string FilePath string FileSize int64 UsageSummary string HasReadingData bool } // HashConflictData is one pending conflict group. type HashConflictData struct { ID string LibraryName string SHA256 string SHAShort string CreatedAt string Items []HashConflictItemData } templ HashConflictCard(conflict HashConflictData) {
@Icon("copy", "h-5 w-5 shrink-0")

Duplicate content

{ fmt.Sprintf("%d copies", len(conflict.Items)) }

Library: { conflict.LibraryName } ยท SHA-256: { conflict.SHAShort }

These files are byte-identical. Keep one copy (reading data from the others is merged in), or keep both if the duplicates are intentional.

for _, item := range conflict.Items { @HashConflictItemCardWrapper(item, conflict.ID) }
} // HashConflictItemCardWrapper renders an item card with its parent conflict ID // for the resolve endpoint targeting. templ HashConflictItemCardWrapper(item HashConflictItemData, conflictID string) {

{ item.Title }

if item.Author != "" {

{ item.Author }

}

{ item.FilePath }

{ fmt.Sprintf("%.1f MB", float64(item.FileSize)/(1024*1024)) } if item.HasReadingData { { item.UsageSummary } } else { { item.UsageSummary } }

} // HashConflictResolved is swapped in place of a card after resolution. templ AdminHashConflicts(user User, conflicts []HashConflictData) { Hash Conflicts - Bookhoard @Header(user, "/admin/hash-conflicts")
@Icon("copy", "h-5 w-5")

Hash Conflicts

Books with identical content stored at more than one path

if len(conflicts) == 0 {
@Icon("check-circle", "h-6 w-6")

No content duplicates detected.

} else {
for _, conflict := range conflicts { @HashConflictCard(conflict) }
}
}