Files
games/features/c4game/components/status.templ
Ryan Hamamura c6885a069b
All checks were successful
CI / Deploy / test (pull_request) Successful in 14s
CI / Deploy / lint (pull_request) Successful in 25s
CI / Deploy / deploy (pull_request) Has been skipped
refactor: rename Go module from c4 to games
Rename module path github.com/ryanhamamura/c4 to
github.com/ryanhamamura/games across go.mod, all source files,
and golangci config.
2026-03-02 20:41:20 -10:00

152 lines
3.6 KiB
Plaintext

package components
import (
"github.com/ryanhamamura/games/config"
"github.com/ryanhamamura/games/connect4"
"github.com/starfederation/datastar-go/datastar"
)
templ StatusBanner(g *connect4.Game, myColor int) {
<div id="c4-status" class={ statusClass(g, myColor) }>
{ statusMessage(g, myColor) }
if g.IsFinished() {
if g.RematchGameID != nil {
<a
class="btn btn-sm bg-white text-gray-800 border-none ml-4"
href={ templ.SafeURL("/games/" + *g.RematchGameID) }
>
Join Rematch
</a>
} else {
<button
class="btn btn-sm bg-white text-gray-800 border-none ml-4"
type="button"
data-on:click={ datastar.PostSSE("/games/%s/rematch", g.ID) }
>
Play again
</button>
}
}
</div>
}
templ PlayerInfo(g *connect4.Game, myColor int) {
<div id="c4-players" class="flex gap-8 mb-2">
for _, info := range playerInfoPairs(g, myColor) {
<div class="flex items-center gap-2">
<span class={ "player-chip " + info.ColorClass }></span>
<span>{ info.Label }</span>
</div>
}
</div>
}
templ InviteLink(gameID string) {
<div class="mt-4 text-center">
<p>Share this link with your opponent:</p>
<div class="bg-base-200 p-4 rounded-lg font-mono break-all my-2">
{ config.Global.AppURL + "/games/" + gameID }
</div>
<button
class="btn btn-sm mt-2"
type="button"
onclick={ copyToClipboard(config.Global.AppURL + "/games/" + gameID) }
>
Copy Link
</button>
</div>
}
script copyToClipboard(url string) {
navigator.clipboard.writeText(url)
}
func statusClass(g *connect4.Game, myColor int) string {
switch g.Status {
case connect4.StatusWaitingForPlayer:
return "alert bg-base-200 text-xl font-bold"
case connect4.StatusInProgress:
if g.CurrentTurn == myColor {
return "alert alert-success text-xl font-bold"
}
return "alert bg-base-200 text-xl font-bold"
case connect4.StatusWon:
if g.Winner != nil && g.Winner.Color == myColor {
return "alert alert-success text-xl font-bold"
}
return "alert alert-error text-xl font-bold"
case connect4.StatusDraw:
return "alert alert-warning text-xl font-bold"
}
return "alert bg-base-200 text-xl font-bold"
}
func statusMessage(g *connect4.Game, myColor int) string {
switch g.Status {
case connect4.StatusWaitingForPlayer:
return "Waiting for opponent..."
case connect4.StatusInProgress:
if g.CurrentTurn == myColor {
return "Your turn!"
}
return opponentName(g, myColor) + "'s turn"
case connect4.StatusWon:
if g.Winner != nil && g.Winner.Color == myColor {
return "You win!"
}
if g.Winner != nil {
return g.Winner.Nickname + " wins!"
}
return "Game over"
case connect4.StatusDraw:
return "It's a draw!"
}
return ""
}
func opponentName(g *connect4.Game, myColor int) string {
for _, p := range g.Players {
if p != nil && p.Color != myColor {
return p.Nickname
}
}
return "Opponent"
}
type playerInfoData struct {
ColorClass string
Label string
}
func playerInfoPairs(g *connect4.Game, myColor int) []playerInfoData {
var result []playerInfoData
var myName, oppName string
var myClass, oppClass string
for _, p := range g.Players {
if p == nil {
continue
}
colorClass := "yellow"
if p.Color == 1 {
colorClass = "red"
}
if p.Color == myColor {
myName = p.Nickname
myClass = colorClass
} else {
oppName = p.Nickname
oppClass = colorClass
}
}
if oppName == "" {
oppName = "Waiting..."
}
result = append(result, playerInfoData{ColorClass: myClass, Label: myName + " (You)"})
result = append(result, playerInfoData{ColorClass: oppClass, Label: oppName})
return result
}