Convert timeSince to more generic timeRelative

This commit is contained in:
Eli Ribble 2026-02-13 21:42:30 +00:00
parent f9d4206bab
commit 26be460041
No known key found for this signature in database
10 changed files with 58 additions and 38 deletions

View file

@ -30,8 +30,8 @@ func addFuncMap(t *template.Template) {
"timeDelta": timeDelta,
"timeElapsed": timeElapsed,
"timeInterval": timeInterval,
"timeSince": timeSince,
"timeSincePtr": timeSincePtr,
"timeRelative": timeRelative,
"timeRelativePtr": timeRelativePtr,
"uuidShort": uuidShort,
}
t.Funcs(funcMap)
@ -179,27 +179,43 @@ func timeInterval(d time.Duration) string {
years := days / 365
return fmt.Sprintf("every %d years", int(math.Round(years)))
}
func timeSincePtr(t *time.Time) string {
if t == nil {
return "never"
}
return timeSince(*t)
}
func timeSince(t time.Time) string {
func timeRelative(t time.Time) string {
now := time.Now()
diff := now.Sub(t)
hours := diff.Hours()
if hours < 1 {
minutes := diff.Minutes()
return fmt.Sprintf("%d minutes ago", int(minutes))
} else if hours < 24 {
return fmt.Sprintf("%d hours ago", int(hours))
if hours > 0 {
if hours < 1 {
minutes := diff.Minutes()
return fmt.Sprintf("%d minutes ago", int(minutes))
} else if hours < 24 {
return fmt.Sprintf("%d hours ago", int(hours))
} else {
days := hours / 24
return fmt.Sprintf("%d days ago", int(days))
}
} else {
days := hours / 24
return fmt.Sprintf("%d days ago", int(days))
if hours < -24 {
days := hours / 24
return fmt.Sprintf("in %d days", -1*int(days))
} else if hours < -1 {
return fmt.Sprintf("in %d hours", -1*int(hours))
} else {
minutes := diff.Minutes()
if minutes > -1 {
seconds := diff.Seconds()
return fmt.Sprintf("in %d seconds", -1*int(seconds))
}
return fmt.Sprintf("in %d minutes", -1*int(minutes))
}
}
}
func timeRelativePtr(t *time.Time) string {
if t == nil {
return "never"
}
return timeRelative(*t)
}
func unescapeHTML(s string) template.HTML {
return template.HTML(s)
}

View file

@ -80,7 +80,7 @@ document.addEventListener("DOMContentLoaded", onLoad);
</div>
<div class="col-md-4 mb-3">
<strong><i class="bi bi-calendar me-2"></i>Created:</strong>
<span>{{ .Report.Created|timeSince }}</span>
<span>{{ .Report.Created|timeRelative }}</span>
</div>
<div class="col-md-4 mb-3">
<strong><i class="bi bi-crosshair me-2"></i>District:</strong>
@ -148,7 +148,7 @@ document.addEventListener("DOMContentLoaded", onLoad);
<div class="timeline">
{{ range .Timeline }}
<div class="timeline-item">
<div class="timeline-date">{{ .At|timeSince }}</div>
<div class="timeline-date">{{ .At|timeRelative }}</div>
<h5 class="mb-1">{{ .Title }}</h5>
<p class="mb-0">{{ .Detail }}</p>
</div>

View file

@ -89,8 +89,8 @@
<a href="/source/{{ .ID }}">{{ .ID|uuidShort }}</a>
</td>
<td>{{ .Type }}</td>
<td>{{ .LastInspected|timeSincePtr }}</td>
<td>{{ .LastTreated|timeSincePtr }}</td>
<td>{{ .LastInspected|timeRelativePtr }}</td>
<td>{{ .LastTreated|timeRelativePtr }}</td>
</tr>
{{ end }}
</tbody>
@ -138,7 +138,7 @@
>
</td>
<td>{{ .Location }}</td>
<td>{{ .Date|timeSincePtr }}</td>
<td>{{ .Date|timeRelativePtr }}</td>
<td>{{ .Action }}</td>
<td>{{ .Notes }}</td>
</tr>
@ -225,7 +225,7 @@
>{{ .LocationID|uuidShort }}</a
>
</td>
<td>{{ .Date|timeSincePtr }}</td>
<td>{{ .Date|timeRelativePtr }}</td>
<td>{{ .Product }}</td>
<td>{{ .Notes }}</td>
</tr>

View file

@ -87,7 +87,7 @@
<div class="flex-grow-1 ms-2">
<p class="mb-0 small">{{ .Message }}</p>
<span class="text-muted x-small"
>{{ .Time | timeSincePtr }}</span
>{{ .Time | timeRelativePtr }}</span
>
</div>
</div>

View file

@ -37,7 +37,9 @@
{{ else }}
<p class="last-refreshed mb-0">
<i class="fas fa-sync-alt me-2"></i>Last updated:
<span id="last-refreshed-time">{{ .LastSync | timeSincePtr }}</span>
<span id="last-refreshed-time"
>{{ .LastSync | timeRelativePtr }}</span
>
<button class="btn btn-sm btn-outline-primary ms-3">
Refresh Data
</button>
@ -56,7 +58,7 @@
<i class="fas fa-clock"></i>
</div>
<h5 class="card-title">Last Data Refresh</h5>
<p class="metric-value">{{ .LastSync | timeSincePtr }}</p>
<p class="metric-value">{{ .LastSync | timeRelativePtr }}</p>
<!-- <p class="card-text text-muted">Last sync: 12:45 PM</p> -->
</div>
</div>
@ -172,7 +174,7 @@
<tbody>
{{ range $i, $sr := .RecentRequests }}
<tr>
<td>{{ $sr.Date | timeSincePtr }}</td>
<td>{{ $sr.Date | timeRelativePtr }}</td>
<td>Service Request</td>
<td>{{ $sr.Location }}</td>
<td><span class="badge bg-success">Completed</span></td>

View file

@ -50,7 +50,9 @@
<div class="flex-grow-1" data-notification-type="{{ .Type }}">
<div>{{ .Message }}</div>
<div class="notification-time">{{ .Time|timeSince }}</div>
<div class="notification-time">
{{ .Time|timeRelative }}
</div>
</div>
<div class="ms-2">
<i class="bi bi-chevron-right text-muted"></i>

View file

@ -39,7 +39,7 @@
{{ range .Uploads }}
<tr class="clickable-row" data-upload-id="{{ .ID }}">
<td>{{ .Status }}</td>
<td>{{ .Created|timeSince }}</td>
<td>{{ .Created|timeRelative }}</td>
</tr>
{{ end }}
</tbody>

View file

@ -86,7 +86,7 @@
</tr>
<tr>
<td><strong>Token Expiration</strong></td>
<td>{{ .ArcGISOAuth.AccessTokenExpires|timeSince }}</td>
<td>{{ .ArcGISOAuth.AccessTokenExpires|timeRelative }}</td>
</tr>
<tr>
<td><strong>Integration Method</strong></td>

View file

@ -149,11 +149,11 @@
<table class="info-table">
<tr>
<td class="info-label">Creation date</td>
<td>{{ .Source.Created|timeSincePtr }}</td>
<td>{{ .Source.Created|timeRelativePtr }}</td>
</tr>
<tr>
<td class="info-label">Edit date</td>
<td>{{ .Source.EditedAt|timeSincePtr }}</td>
<td>{{ .Source.EditedAt|timeRelativePtr }}</td>
</tr>
<tr>
<td class="info-label">Larva Inspect Interval</td>
@ -181,7 +181,7 @@
</tr>
<tr>
<td class="info-label">Last Inspect Date</td>
<td>{{ .Source.LastInspectionDate|timeSincePtr }}</td>
<td>{{ .Source.LastInspectionDate|timeRelativePtr }}</td>
</tr>
<tr>
<td class="info-label">Last Inspect Species</td>
@ -197,7 +197,7 @@
</tr>
<tr>
<td class="info-label">Last Treat Date</td>
<td>{{ .Source.LastTreatmentDate|timeSincePtr }}</td>
<td>{{ .Source.LastTreatmentDate|timeRelativePtr }}</td>
</tr>
<tr>
<td class="info-label">Last Treat Product</td>
@ -213,7 +213,7 @@
</tr>
<tr>
<td class="info-label">Next action date scheduled:</td>
<td>{{ .Source.NextActionScheduledDate|timeSincePtr }}</td>
<td>{{ .Source.NextActionScheduledDate|timeRelativePtr }}</td>
</tr>
<tr>
<td class="info-label">Treatment Cadence:</td>
@ -274,7 +274,7 @@
<tbody>
{{ range .Treatments }}
<tr>
<td>{{ .Date|timeSincePtr }}</td>
<td>{{ .Date|timeRelativePtr }}</td>
<td>{{ .Product }}</td>
<td class="time-delta-neutral">
{{ .CadenceDelta|timeDelta }}
@ -307,7 +307,7 @@
<tbody>
{{ range .Inspections }}
<tr>
<td>{{ .Date|timeSincePtr }}</td>
<td>{{ .Date|timeRelativePtr }}</td>
<td>{{ .Action }}</td>
<td>{{ .Notes }}</td>
</tr>
@ -351,7 +351,7 @@
<!-- Trap 1 with multiple collections -->
{{ range .Counts }}
<tr>
<td>{{ .Ended|timeSincePtr }}</td>
<td>{{ .Ended|timeRelativePtr }}</td>
<td>{{ .Females }}</td>
<td>{{ .Males }}</td>
<td>{{ .Total }}</td>

View file

@ -115,7 +115,7 @@
<!-- Trap 1 with multiple collections -->
{{ range .Trap.Collections }}
<tr>
<td>{{ .EndDateTime|timeSincePtr }}</td>
<td>{{ .EndDateTime|timeRelativePtr }}</td>
<td>{{ .GlobalID }}</td>
<td>{{ .Count.Females }}</td>
<td>{{ .Count.Males }}</td>