Skip to content

Commit 042166b

Browse files
ralyodioclaude
andcommitted
members: show joined date in admin + public lists; 'last active: X ago'
Admin Users view appends 'joined YYYY-MM-DD'. Public member directory shows 'last active: N days ago' for offline members plus the joined date, both sourced from store.User.CreatedAt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 28ad368 commit 042166b

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

internal/admin/admin.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ func (m Model) viewUsers() (string, string) {
344344
if u.EmailVerified {
345345
flags = append(flags, "verified")
346346
}
347+
if !u.CreatedAt.IsZero() {
348+
flags = append(flags, "joined "+u.CreatedAt.Format("2006-01-02"))
349+
}
347350
name := u.Name
348351
if u.Banned {
349352
name = warnStyle.Render(name + " [BANNED]")

plugins/members/members.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type person struct {
5151
online bool
5252
lastSeen time.Time
5353
seenOK bool
54+
joined time.Time
5455
}
5556

5657
type model struct {
@@ -92,7 +93,7 @@ func (m *model) load() tea.Cmd {
9293
if u.Name == me {
9394
continue // don't list yourself in the directory
9495
}
95-
p := person{name: u.Name, kind: u.Kind, online: online[strings.ToLower(u.Name)]}
96+
p := person{name: u.Name, kind: u.Kind, online: online[strings.ToLower(u.Name)], joined: u.CreatedAt}
9697
if t, ok, _ := st.LastSeen(u.ID); ok {
9798
p.lastSeen, p.seenOK = t, true
9899
}
@@ -410,9 +411,12 @@ func (m *model) listView() string {
410411
c = cur.Render("❯ ")
411412
name = sel.Render(name)
412413
}
413-
seen := "online"
414+
seen := "online now"
414415
if !p.online {
415-
seen = "last " + relTime(p.lastSeen, p.seenOK)
416+
seen = "last active: " + relTimeLong(p.lastSeen, p.seenOK)
417+
}
418+
if !p.joined.IsZero() {
419+
seen += " · joined " + p.joined.Format("2006-01-02")
416420
}
417421
row := fmt.Sprintf("%s%s %s %-20s %-8s %s", c, box, dot, name, p.kind, dim.Render(seen))
418422
s += row + "\n"
@@ -507,3 +511,28 @@ func relTime(t time.Time, ok bool) string {
507511
return fmt.Sprintf("%dd", int(d.Hours()/24))
508512
}
509513
}
514+
515+
// relTimeLong renders a spelled-out "3 days ago" / "2 hours ago" / "just now"
516+
// age for the public directory. ok=false → "never".
517+
func relTimeLong(t time.Time, ok bool) string {
518+
if !ok || t.IsZero() {
519+
return "never"
520+
}
521+
d := time.Since(t)
522+
plural := func(n int, unit string) string {
523+
if n == 1 {
524+
return fmt.Sprintf("1 %s ago", unit)
525+
}
526+
return fmt.Sprintf("%d %ss ago", n, unit)
527+
}
528+
switch {
529+
case d < time.Minute:
530+
return "just now"
531+
case d < time.Hour:
532+
return plural(int(d.Minutes()), "minute")
533+
case d < 24*time.Hour:
534+
return plural(int(d.Hours()), "hour")
535+
default:
536+
return plural(int(d.Hours()/24), "day")
537+
}
538+
}

0 commit comments

Comments
 (0)