From 76987adcebc9782ddbb16b4d409416d53765dd99 Mon Sep 17 00:00:00 2001 From: Haelnorr Date: Fri, 6 Mar 2026 21:03:51 +1100 Subject: [PATCH] added better links to teams and players --- internal/handlers/season_league_table.go | 2 +- internal/view/component/links/links.templ | 54 +++++++++++++++++++ .../view/seasonsview/fixture_detail.templ | 31 ++++++----- .../seasonsview/fixture_review_result.templ | 33 ++++++++---- .../season_league_free_agents.templ | 5 +- .../seasonsview/season_league_table.templ | 19 +++---- .../season_league_team_detail.templ | 11 ++-- .../view/teamsview/detail_player_stats.templ | 5 +- 8 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 internal/view/component/links/links.templ diff --git a/internal/handlers/season_league_table.go b/internal/handlers/season_league_table.go index c870109..a9fb7be 100644 --- a/internal/handlers/season_league_table.go +++ b/internal/handlers/season_league_table.go @@ -62,7 +62,7 @@ func SeasonLeagueTablePage( if r.Method == "GET" { renderSafely(seasonsview.SeasonLeagueTablePage(season, league, leaderboard), s, r, w) } else { - renderSafely(seasonsview.SeasonLeagueTable(leaderboard), s, r, w) + renderSafely(seasonsview.SeasonLeagueTable(season, league, leaderboard), s, r, w) } }) } diff --git a/internal/view/component/links/links.templ b/internal/view/component/links/links.templ new file mode 100644 index 0000000..ed6245e --- /dev/null +++ b/internal/view/component/links/links.templ @@ -0,0 +1,54 @@ +package links + +import "git.haelnorr.com/h/oslstats/internal/db" +import "fmt" + +// PlayerLink renders a player name as a clickable link to their profile page. +// The player's DisplayName() is used as the link text. +templ PlayerLink(player *db.Player) { + + { player.DisplayName() } + +} + +// PlayerLinkFromStats renders a player name link using a player ID and name string. +// This is useful when only aggregated stats are available (no full Player object). +templ PlayerLinkFromStats(playerID int, playerName string) { + + { playerName } + +} + +// TeamLinkInSeason renders a team name as a clickable link to the team's +// season-specific detail page, with an optional color dot prefix. +templ TeamLinkInSeason(team *db.Team, season *db.Season, league *db.League) { + + if team.Color != "" { + + } + { team.Name } + +} + +// TeamNameLinkInSeason renders just the team name as a clickable link (no color dot). +// Useful where the color dot is already rendered separately or in inline contexts. +templ TeamNameLinkInSeason(team *db.Team, season *db.Season, league *db.League) { + + { team.Name } + +} diff --git a/internal/view/seasonsview/fixture_detail.templ b/internal/view/seasonsview/fixture_detail.templ index c9d34cc..26e8b77 100644 --- a/internal/view/seasonsview/fixture_detail.templ +++ b/internal/view/seasonsview/fixture_detail.templ @@ -4,6 +4,7 @@ import "git.haelnorr.com/h/oslstats/internal/db" import "git.haelnorr.com/h/oslstats/internal/permissions" import "git.haelnorr.com/h/oslstats/internal/contexts" import "git.haelnorr.com/h/oslstats/internal/view/baseview" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" import "sort" import "strings" @@ -147,8 +148,8 @@ templ fixtureOverviewTab( }
- @fixtureTeamSection(fixture.HomeTeam, rosters["home"], "home", result) - @fixtureTeamSection(fixture.AwayTeam, rosters["away"], "away", result) + @fixtureTeamSection(fixture.HomeTeam, rosters["home"], "home", result, fixture.Season, fixture.League) + @fixtureTeamSection(fixture.AwayTeam, rosters["away"], "away", result, fixture.Season, fixture.League)
} @@ -603,7 +604,7 @@ templ forfeitModal(fixture *db.Fixture) { } -templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side string, result *db.FixtureResult) { +templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side string, result *db.FixtureResult, season *db.Season, league *db.League) { {{ // Separate playing and bench players var playing []*db.PlayerWithPlayStatus @@ -640,8 +641,8 @@ templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side }}
-

- { team.Name } +

+ @links.TeamNameLinkInSeason(team, season, league)

if team.Color != "" { for _, p := range playing { - + - { p.Player.DisplayName() } + @links.PlayerLink(p.Player) if p.IsManager { ★ @@ -715,7 +716,7 @@ templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side for _, p := range bench {
- { p.Player.DisplayName() } + @links.PlayerLink(p.Player) if p.IsManager { @@ -737,8 +738,8 @@ templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side
for _, p := range playing {
- - { p.Player.DisplayName() } + + @links.PlayerLink(p.Player) if p.IsManager { @@ -760,7 +761,7 @@ templ fixtureTeamSection(team *db.Team, players []*db.PlayerWithPlayStatus, side for _, p := range bench {
- { p.Player.DisplayName() } + @links.PlayerLink(p.Player) if p.IsManager { @@ -840,7 +841,9 @@ templ fixtureFreeAgentSection( for _, n := range homeNominated {
- { n.Player.DisplayName() } + + @links.PlayerLink(n.Player) + FA @@ -875,7 +878,9 @@ templ fixtureFreeAgentSection( for _, n := range awayNominated {
- { n.Player.DisplayName() } + + @links.PlayerLink(n.Player) + FA diff --git a/internal/view/seasonsview/fixture_review_result.templ b/internal/view/seasonsview/fixture_review_result.templ index c41e931..2921621 100644 --- a/internal/view/seasonsview/fixture_review_result.templ +++ b/internal/view/seasonsview/fixture_review_result.templ @@ -2,6 +2,7 @@ package seasonsview import "git.haelnorr.com/h/oslstats/internal/db" import "git.haelnorr.com/h/oslstats/internal/view/baseview" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" templ FixtureReviewResultPage( @@ -22,7 +23,13 @@ templ FixtureReviewResultPage(

Review Match Result

- { fixture.HomeTeam.Name } vs { fixture.AwayTeam.Name } + + @links.TeamNameLinkInSeason(fixture.HomeTeam, fixture.Season, fixture.League) + + vs + + @links.TeamNameLinkInSeason(fixture.AwayTeam, fixture.Season, fixture.League) + Round { fmt.Sprint(fixture.Round) } @@ -96,12 +103,16 @@ templ FixtureReviewResultPage(

-

{ fixture.HomeTeam.Name }

+

+ @links.TeamNameLinkInSeason(fixture.HomeTeam, fixture.Season, fixture.League) +

{ fmt.Sprint(result.HomeScore) }

-

{ fixture.AwayTeam.Name }

+

+ @links.TeamNameLinkInSeason(fixture.AwayTeam, fixture.Season, fixture.League) +

{ fmt.Sprint(result.AwayScore) }

@@ -127,8 +138,8 @@ templ FixtureReviewResultPage(
- @reviewTeamStats(fixture.HomeTeam, result, "home") - @reviewTeamStats(fixture.AwayTeam, result, "away") + @reviewTeamStats(fixture.HomeTeam, result, "home", fixture.Season, fixture.League) + @reviewTeamStats(fixture.AwayTeam, result, "away", fixture.Season, fixture.League)
@@ -164,7 +175,7 @@ templ FixtureReviewResultPage( } } -templ reviewTeamStats(team *db.Team, result *db.FixtureResult, side string) { +templ reviewTeamStats(team *db.Team, result *db.FixtureResult, side string, season *db.Season, league *db.League) { {{ // Collect unique players for this team across all periods // We'll show the period 3 (final/cumulative) stats @@ -197,7 +208,7 @@ templ reviewTeamStats(team *db.Team, result *db.FixtureResult, side string) { } else { Away — } - { team.Name } + @links.TeamNameLinkInSeason(team, season, league)
@@ -218,10 +229,12 @@ templ reviewTeamStats(team *db.Team, result *db.FixtureResult, side string) { for _, ps := range finalStats { - + - { ps.Username } - if ps.PlayerID == nil { + if ps.PlayerID != nil { + @links.PlayerLinkFromStats(*ps.PlayerID, ps.Username) + } else { + { ps.Username } ? } if ps.Stats.IsFreeAgent { diff --git a/internal/view/seasonsview/season_league_free_agents.templ b/internal/view/seasonsview/season_league_free_agents.templ index 7ff354b..b08291c 100644 --- a/internal/view/seasonsview/season_league_free_agents.templ +++ b/internal/view/seasonsview/season_league_free_agents.templ @@ -3,6 +3,7 @@ package seasonsview import "git.haelnorr.com/h/oslstats/internal/db" import "git.haelnorr.com/h/oslstats/internal/permissions" import "git.haelnorr.com/h/oslstats/internal/contexts" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" templ SeasonLeagueFreeAgentsPage(season *db.Season, league *db.League, freeAgents []*db.SeasonLeagueFreeAgent, availablePlayers []*db.Player) { @@ -53,9 +54,9 @@ templ SeasonLeagueFreeAgents(season *db.Season, league *db.League, freeAgents [] for _, fa := range freeAgents { - + - { fa.Player.DisplayName() } + @links.PlayerLink(fa.Player) FREE AGENT diff --git a/internal/view/seasonsview/season_league_table.templ b/internal/view/seasonsview/season_league_table.templ index ae80916..560c507 100644 --- a/internal/view/seasonsview/season_league_table.templ +++ b/internal/view/seasonsview/season_league_table.templ @@ -1,15 +1,16 @@ package seasonsview import "git.haelnorr.com/h/oslstats/internal/db" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" templ SeasonLeagueTablePage(season *db.Season, league *db.League, leaderboard []*db.LeaderboardEntry) { @SeasonLeagueLayout("table", season, league) { - @SeasonLeagueTable(leaderboard) + @SeasonLeagueTable(season, league, leaderboard) } } -templ SeasonLeagueTable(leaderboard []*db.LeaderboardEntry) { +templ SeasonLeagueTable(season *db.Season, league *db.League, leaderboard []*db.LeaderboardEntry) { if len(leaderboard) == 0 {

No teams in this league yet.

@@ -43,7 +44,7 @@ templ SeasonLeagueTable(leaderboard []*db.LeaderboardEntry) { for _, entry := range leaderboard { - @leaderboardRow(entry) + @leaderboardRow(entry, season, league) } @@ -52,7 +53,7 @@ templ SeasonLeagueTable(leaderboard []*db.LeaderboardEntry) { } } -templ leaderboardRow(entry *db.LeaderboardEntry) { +templ leaderboardRow(entry *db.LeaderboardEntry, season *db.Season, league *db.League) { {{ r := entry.Record goalDiff := r.GoalsFor - r.GoalsAgainst @@ -68,15 +69,7 @@ templ leaderboardRow(entry *db.LeaderboardEntry) { { fmt.Sprint(entry.Position) } -
- if entry.Team.Color != "" { - - } - { entry.Team.Name } -
+ @links.TeamLinkInSeason(entry.Team, season, league) { fmt.Sprint(r.Played) } diff --git a/internal/view/seasonsview/season_league_team_detail.templ b/internal/view/seasonsview/season_league_team_detail.templ index 3019d01..709ffa4 100644 --- a/internal/view/seasonsview/season_league_team_detail.templ +++ b/internal/view/seasonsview/season_league_team_detail.templ @@ -4,6 +4,7 @@ import "git.haelnorr.com/h/oslstats/internal/db" import "git.haelnorr.com/h/oslstats/internal/permissions" import "git.haelnorr.com/h/oslstats/internal/contexts" import "git.haelnorr.com/h/oslstats/internal/view/baseview" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" import "sort" import "time" @@ -154,7 +155,9 @@ templ TeamRosterSection(twr *db.TeamWithRoster, available []*db.Player) {
if twr.Manager != nil {
- { twr.Manager.Name } + + @links.PlayerLink(twr.Manager) + ★ Manager @@ -162,7 +165,7 @@ templ TeamRosterSection(twr *db.TeamWithRoster, available []*db.Player) { } for _, player := range rosterPlayers {
- { player.Name } + @links.PlayerLink(player)
}
@@ -680,7 +683,9 @@ templ playerStatsSection(playerStats []*db.AggregatedPlayerStats) { for _, ps := range playerStats { - { ps.PlayerName } + + @links.PlayerLinkFromStats(ps.PlayerID, ps.PlayerName) + { fmt.Sprint(ps.GamesPlayed) } { fmt.Sprint(ps.PeriodsPlayed) } { fmt.Sprint(ps.Score) } diff --git a/internal/view/teamsview/detail_player_stats.templ b/internal/view/teamsview/detail_player_stats.templ index 085c7cb..ad7301f 100644 --- a/internal/view/teamsview/detail_player_stats.templ +++ b/internal/view/teamsview/detail_player_stats.templ @@ -1,6 +1,7 @@ package teamsview import "git.haelnorr.com/h/oslstats/internal/db" +import "git.haelnorr.com/h/oslstats/internal/view/component/links" import "fmt" import "sort" @@ -108,7 +109,9 @@ templ playerStatsTable(playerStats []*db.TeamAllTimePlayerStats, statType string { fmt.Sprint(i + 1) } - { ps.PlayerName } + + @links.PlayerLinkFromStats(ps.PlayerID, ps.PlayerName) + { fmt.Sprint(ps.SeasonsPlayed) } { fmt.Sprint(ps.PeriodsPlayed) } if statType == "goals" {