added team rosters to season_league overview

This commit is contained in:
2026-02-20 20:08:57 +11:00
parent e8b492ce4d
commit f2e68ca6eb
4 changed files with 63 additions and 6 deletions

View File

@@ -75,6 +75,26 @@ func GetTeamRoster(ctx context.Context, tx bun.Tx, seasonShortName, leagueShortN
return twr, nil
}
// GetManagersByTeam returns a map of teamID -> manager Player for all teams in a season/league
func GetManagersByTeam(ctx context.Context, tx bun.Tx, seasonID, leagueID int) (map[int]*Player, error) {
rosters := []*TeamRoster{}
err := tx.NewSelect().
Model(&rosters).
Where("tr.season_id = ?", seasonID).
Where("tr.league_id = ?", leagueID).
Where("tr.is_manager = true").
Relation("Player").
Scan(ctx)
if err != nil {
return nil, errors.Wrap(err, "tx.NewSelect")
}
result := make(map[int]*Player, len(rosters))
for _, r := range rosters {
result[r.TeamID] = r.Player
}
return result, nil
}
func AddPlayerToTeam(ctx context.Context, tx bun.Tx, seasonID, leagueID, teamID, playerID int, manager bool, audit *AuditMeta) error {
season, err := GetByID[Season](tx, seasonID).Get(ctx)
if err != nil {

View File

@@ -1005,6 +1005,9 @@
.p-8 {
padding: calc(var(--spacing) * 8);
}
.px-1\.5 {
padding-inline: calc(var(--spacing) * 1.5);
}
.px-2 {
padding-inline: calc(var(--spacing) * 2);
}
@@ -1044,6 +1047,9 @@
.pt-2 {
padding-top: calc(var(--spacing) * 2);
}
.pt-3 {
padding-top: calc(var(--spacing) * 3);
}
.pt-4 {
padding-top: calc(var(--spacing) * 4);
}

View File

@@ -25,6 +25,7 @@ func SeasonLeagueTeamsPage(
var league *db.League
var teams []*db.Team
var available []*db.Team
var managers map[int]*db.Player
if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) {
var err error
@@ -45,15 +46,20 @@ func SeasonLeagueTeamsPage(
return false, errors.Wrap(err, "db.GetList[Team]")
}
managers, err = db.GetManagersByTeam(ctx, tx, season.ID, league.ID)
if err != nil {
return false, errors.Wrap(err, "db.GetManagersByTeam")
}
return true, nil
}); !ok {
return
}
if r.Method == "GET" {
renderSafely(seasonsview.SeasonLeagueTeamsPage(season, league, teams, available), s, r, w)
renderSafely(seasonsview.SeasonLeagueTeamsPage(season, league, teams, available, managers), s, r, w)
} else {
renderSafely(seasonsview.SeasonLeagueTeams(season, league, teams, available), s, r, w)
renderSafely(seasonsview.SeasonLeagueTeams(season, league, teams, available, managers), s, r, w)
}
})
}

View File

@@ -5,9 +5,9 @@ import "git.haelnorr.com/h/oslstats/internal/permissions"
import "git.haelnorr.com/h/oslstats/internal/contexts"
import "fmt"
templ SeasonLeagueTeamsPage(season *db.Season, league *db.League, teams []*db.Team, allTeams []*db.Team) {
templ SeasonLeagueTeamsPage(season *db.Season, league *db.League, teams []*db.Team, allTeams []*db.Team, managers map[int]*db.Player) {
@SeasonLeagueLayout("teams", season, league) {
@SeasonLeagueTeams(season, league, teams, allTeams)
@SeasonLeagueTeams(season, league, teams, allTeams, managers)
}
}
@@ -94,7 +94,7 @@ templ addTeamModal(season *db.Season, league *db.League, existingTeams []*db.Tea
</div>
}
templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team, allTeams []*db.Team) {
templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team, allTeams []*db.Team, managers map[int]*db.Player) {
{{
permCache := contexts.Permissions(ctx)
canAddTeam := permCache.HasPermission(permissions.TeamsAddToLeague)
@@ -122,6 +122,9 @@ templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team,
} else {
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
for _, team := range teams {
{{
manager := managers[team.ID]
}}
<a
href={ templ.SafeURL(fmt.Sprintf("/seasons/%s/leagues/%s/teams/%d", season.ShortName, league.ShortName, team.ID)) }
class="bg-surface0 border border-surface1 rounded-lg p-6 hover:bg-surface1 transition-colors hover:cursor-pointer block"
@@ -135,7 +138,7 @@ templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team,
></div>
}
</div>
<div class="flex items-center gap-2 text-sm flex-wrap">
<div class="flex items-center gap-2 text-sm flex-wrap mb-3">
<span class="px-2 py-1 bg-mantle rounded text-subtext0 font-mono">
{ team.ShortName }
</span>
@@ -143,6 +146,28 @@ templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team,
{ team.AltShortName }
</span>
</div>
<!-- Roster -->
if len(team.Players) == 0 {
<p class="text-subtext1 text-xs italic">No roster</p>
} else {
<div class="border-t border-surface1 pt-3 space-y-1">
if manager != nil {
<div class="flex items-center justify-between">
<span class="text-sm text-text font-medium">{ manager.Name }</span>
<span class="text-xs px-1.5 py-0.5 bg-yellow/20 text-yellow rounded font-medium">
&#9733; Mgr
</span>
</div>
}
for _, player := range team.Players {
if manager == nil || player.ID != manager.ID {
<div>
<span class="text-sm text-subtext0">{ player.Name }</span>
</div>
}
}
</div>
}
</a>
}
</div>