fixtures #2

Merged
h merged 20 commits from fixtures into master 2026-02-23 20:38:26 +11:00
4 changed files with 63 additions and 6 deletions
Showing only changes of commit 9e3355deb6 - Show all commits

View File

@@ -75,6 +75,26 @@ func GetTeamRoster(ctx context.Context, tx bun.Tx, seasonShortName, leagueShortN
return twr, nil 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 { 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) season, err := GetByID[Season](tx, seasonID).Get(ctx)
if err != nil { if err != nil {

View File

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

View File

@@ -25,6 +25,7 @@ func SeasonLeagueTeamsPage(
var league *db.League var league *db.League
var teams []*db.Team var teams []*db.Team
var available []*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) { if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) {
var err error var err error
@@ -45,15 +46,20 @@ func SeasonLeagueTeamsPage(
return false, errors.Wrap(err, "db.GetList[Team]") 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 return true, nil
}); !ok { }); !ok {
return return
} }
if r.Method == "GET" { 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 { } 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 "git.haelnorr.com/h/oslstats/internal/contexts"
import "fmt" 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) { @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> </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) permCache := contexts.Permissions(ctx)
canAddTeam := permCache.HasPermission(permissions.TeamsAddToLeague) canAddTeam := permCache.HasPermission(permissions.TeamsAddToLeague)
@@ -122,6 +122,9 @@ templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team,
} else { } else {
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
for _, team := range teams { for _, team := range teams {
{{
manager := managers[team.ID]
}}
<a <a
href={ templ.SafeURL(fmt.Sprintf("/seasons/%s/leagues/%s/teams/%d", season.ShortName, league.ShortName, team.ID)) } 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" 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> </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"> <span class="px-2 py-1 bg-mantle rounded text-subtext0 font-mono">
{ team.ShortName } { team.ShortName }
</span> </span>
@@ -143,6 +146,28 @@ templ SeasonLeagueTeams(season *db.Season, league *db.League, teams []*db.Team,
{ team.AltShortName } { team.AltShortName }
</span> </span>
</div> </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> </a>
} }
</div> </div>