feat(ui): use timezone-aware time formatting across all templates

Replace hardcoded .Format() calls with FormatInTimezone() and
FormatTimestamptzInTimezone() helpers so all timestamps display in
the user's selected timezone.

Changes:
- book_detail.templ: remove incorrect templates. package prefix
- book_detail_modals.templ: add User param to ProgressSyncModal so
  timezone is available; convert Timestamp to FormatInTimezone()
- devices.templ: convert LastSync and LastSeen to FormatInTimezone()
- conflicts.templ: convert CreatedAt to FormatInTimezone()
- admin_users.templ: convert CreatedAt to FormatInTimezone() using
  currentUser.Timezone

Note: DatePublished is kept as a plain date format (MM-DD-YYYY) since
it is a pgtype.Date, not a timestamp, and does not need timezone
conversion.
This commit is contained in:
2026-04-29 20:32:51 -04:00
parent 6b958cab39
commit 13edfdcf1a
5 changed files with 8 additions and 8 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ templ AdminUsers(currentUser User, users []User, adminCount int) {
</td> </td>
<!-- Created --> <!-- Created -->
<td class="px-6 py-4 whitespace-nowrap"> <td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm" style="color: var(--text-secondary)">{ user.CreatedAt.Format("01-02-2006") }</div> <div class="text-sm" style="color: var(--text-secondary)">{ FormatInTimezone(user.CreatedAt, currentUser.Timezone) }</div>
</td> </td>
<!-- Actions --> <!-- Actions -->
<td class="px-6 py-4 whitespace-nowrap text-right"> <td class="px-6 py-4 whitespace-nowrap text-right">
+2 -2
View File
@@ -250,7 +250,7 @@ templ BookDetail(user User, book handlers.MediaDetail, errorMessage string) {
if book.ReadingProgress.LastReadAt.Valid { if book.ReadingProgress.LastReadAt.Valid {
<div> <div>
<p style="color: var(--text-secondary)">Last Read</p> <p style="color: var(--text-secondary)">Last Read</p>
<p>{ templates.FormatTimestamptzInTimezone(book.ReadingProgress.LastReadAt, user.Timezone) }</p> <p>{ FormatTimestamptzInTimezone(book.ReadingProgress.LastReadAt, user.Timezone) }</p>
</div> </div>
} }
if book.ReadingProgress.LastSyncSource.Valid { if book.ReadingProgress.LastSyncSource.Valid {
@@ -501,7 +501,7 @@ templ BookDetail(user User, book handlers.MediaDetail, errorMessage string) {
} }
</div> </div>
<!-- Modals --> <!-- Modals -->
@ProgressSyncModal(book) @ProgressSyncModal(user, book)
@NotesHighlightsModal(book) @NotesHighlightsModal(book)
@ErrorToast(errorMessage) @ErrorToast(errorMessage)
</body> </body>
+2 -2
View File
@@ -6,7 +6,7 @@ import (
) )
// ProgressSyncModal shows progress from all devices for manual review // ProgressSyncModal shows progress from all devices for manual review
templ ProgressSyncModal(book handlers.MediaDetail) { templ ProgressSyncModal(user User, book handlers.MediaDetail) {
<div <div
id="progress-sync-modal" id="progress-sync-modal"
class="hidden fixed inset-0 z-50 flex items-center justify-center overflow-y-auto" class="hidden fixed inset-0 z-50 flex items-center justify-center overflow-y-auto"
@@ -65,7 +65,7 @@ templ ProgressSyncModal(book handlers.MediaDetail) {
{ source } { source }
</span> </span>
<p class="text-xs" style="color: var(--text-secondary);"> <p class="text-xs" style="color: var(--text-secondary);">
{ data.Timestamp.Format("01-02-2006 03:04 PM:05") } { FormatInTimezone(data.Timestamp, user.Timezone) }
</p> </p>
</div> </div>
<div class="text-right"> <div class="text-right">
+1 -1
View File
@@ -111,7 +111,7 @@ templ Conflicts(user User, conflicts []handlers.ConflictDetailResponse, total in
</button> </button>
</div> </div>
<div class="text-sm" style="color: var(--text-secondary)"> <div class="text-sm" style="color: var(--text-secondary)">
Created: { conflict.CreatedAt.Format("01-02-2006 03:04:05 PM") } Created: { FormatInTimezone(conflict.CreatedAt, user.Timezone) }
if conflict.ResolvedBy != "" { if conflict.ResolvedBy != "" {
| Resolved by: { conflict.ResolvedBy } | Resolved by: { conflict.ResolvedBy }
} }
+2 -2
View File
@@ -80,7 +80,7 @@ templ Devices(user User, devices []handlers.DeviceInfo, pendingRegistrations []P
<div class="flex justify-between"> <div class="flex justify-between">
<span style="color: var(--text-secondary)">Last Sync</span> <span style="color: var(--text-secondary)">Last Sync</span>
if device.LastSync != nil { if device.LastSync != nil {
<span style="color: var(--text-primary)">{ device.LastSync.Format("01-02-2006 03:04 PM") }</span> <span style="color: var(--text-primary)">{ FormatInTimezone(*device.LastSync, user.Timezone) }</span>
} else { } else {
<span style="color: var(--text-primary)">Never</span> <span style="color: var(--text-primary)">Never</span>
} }
@@ -88,7 +88,7 @@ templ Devices(user User, devices []handlers.DeviceInfo, pendingRegistrations []P
<div class="flex justify-between"> <div class="flex justify-between">
<span style="color: var(--text-secondary)">Last Seen</span> <span style="color: var(--text-secondary)">Last Seen</span>
if device.LastSeen != nil { if device.LastSeen != nil {
<span style="color: var(--text-primary)">{ device.LastSeen.Format("01-02-2006 03:04 PM") }</span> <span style="color: var(--text-primary)">{ FormatInTimezone(*device.LastSeen, user.Timezone) }</span>
} else { } else {
<span style="color: var(--text-primary)">Never</span> <span style="color: var(--text-primary)">Never</span>
} }