package ui import ( "fmt" "time" "github.com/ryanhamamura/via/h" ) type GameListItem struct { ID string Status int OpponentName string IsMyTurn bool LastPlayed time.Time } func GameList(games []GameListItem) h.H { if len(games) == 0 { return nil } var items []h.H for _, g := range games { items = append(items, gameListEntry(g)) } listItems := []h.H{h.Class("game-list-items")} listItems = append(listItems, items...) return h.Div(h.Class("game-list"), h.H3(h.Text("Your Games")), h.Div(listItems...), ) } func gameListEntry(g GameListItem) h.H { statusText, statusClass := getStatusDisplay(g) return h.A( h.Href("/game/"+g.ID), h.Class("game-entry"), h.Div(h.Class("game-entry-main"), h.Span(h.Class("opponent-name"), h.Text(getOpponentDisplay(g))), h.Span(h.Class("game-status "+statusClass), h.Text(statusText)), ), h.Div(h.Class("game-entry-meta"), h.Span(h.Class("time-ago"), h.Text(formatTimeAgo(g.LastPlayed))), ), ) } func getStatusDisplay(g GameListItem) (string, string) { switch g.Status { case 0: // Waiting return "Waiting for opponent", "waiting" case 1: // In progress if g.IsMyTurn { return "Your turn!", "your-turn" } return "Opponent's turn", "opponent-turn" } return "", "" } func getOpponentDisplay(g GameListItem) string { if g.OpponentName == "" { return "Waiting for opponent..." } return "vs " + g.OpponentName } func formatTimeAgo(t time.Time) string { if t.IsZero() { return "" } duration := time.Since(t) if duration < time.Minute { return "just now" } if duration < time.Hour { mins := int(duration.Minutes()) if mins == 1 { return "1 minute ago" } return fmt.Sprintf("%d minutes ago", mins) } if duration < 24*time.Hour { hours := int(duration.Hours()) if hours == 1 { return "1 hour ago" } return fmt.Sprintf("%d hours ago", hours) } days := int(duration.Hours() / 24) if days == 1 { return "yesterday" } return fmt.Sprintf("%d days ago", days) }