package ui import ( "fmt" "time" "github.com/ryanhamamura/c4/game" "github.com/ryanhamamura/via/h" ) type GameListItem struct { ID string Status int OpponentName string IsMyTurn bool LastPlayed time.Time } func GameList(games []GameListItem, deleteClick func(id string) h.H) h.H { if len(games) == 0 { return nil } var items []h.H for _, g := range games { items = append(items, gameListEntry(g, deleteClick)) } listItems := []h.H{h.Class("flex flex-col gap-2")} listItems = append(listItems, items...) return h.Div(h.Class("mt-8 text-left"), h.H3(h.Class("mb-4 text-center text-lg font-bold"), h.Text("Your Games")), h.Div(listItems...), ) } func gameListEntry(g GameListItem, deleteClick func(id string) h.H) h.H { statusText, statusClass := getStatusDisplay(g) return h.Div(h.Class("flex items-center gap-2 p-2 bg-base-200 rounded-lg transition-colors hover:bg-base-300"), h.A( h.Href("/game/"+g.ID), h.Class("flex-1 flex justify-between items-center px-2 py-1 no-underline text-base-content"), h.Div(h.Class("flex flex-col gap-1"), h.Span(h.Class("font-bold"), h.Text(getOpponentDisplay(g))), h.Span(h.Class(statusClass), h.Text(statusText)), ), h.Div( h.Span(h.Class("text-xs opacity-60"), h.Text(formatTimeAgo(g.LastPlayed))), ), ), h.Button( h.Type("button"), h.Class("btn btn-ghost btn-sm btn-square hover:btn-error"), h.Text("\u00d7"), deleteClick(g.ID), ), ) } func getStatusDisplay(g GameListItem) (string, string) { switch game.GameStatus(g.Status) { case game.StatusWaitingForPlayer: return "Waiting for opponent", "text-sm opacity-60" case game.StatusInProgress: if g.IsMyTurn { return "Your turn!", "text-sm text-success font-bold" } return "Opponent's turn", "text-sm" } 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) }