Add Team functions

This commit is contained in:
2025-09-22 12:53:46 -04:00
parent 3daa3b81b3
commit dc83a18d76
48 changed files with 2364 additions and 633 deletions
@@ -0,0 +1,307 @@
@using Microsoft.EntityFrameworkCore
@using WebApp.Models
@page "/teams/printout"
@inject IConfiguration Configuration
@inject AppDbContext Context
<PageTitle>@Configuration["ChapterSettings:Shortname"] TSA Teams @Configuration["ChapterSettings:CompetitionYear"]</PageTitle>
<MudText Typo="Typo.h3">@Configuration["ChapterSettings:Shortname"] TSA Teams @Configuration["ChapterSettings:CompetitionYear"]</MudText>
<MudText Typo="Typo.h5" Class="mb-4">Yearly theme: Unity Through Community</MudText>
@if (_teams == null)
{
<p><em>Loading...</em></p>
}
else
{
<MudContainer Class="mt-3 mb-1 nobrk">
<MudTable Items="_teams">
<HeaderContent>
<MudTh>Team</MudTh>
<MudTh></MudTh>
@for (var i = 0; i <= _maxTeamSize; i++)
{
<MudTh></MudTh>
}
</HeaderContent>
<RowTemplate>
<MudTd>
@context.ToString()
</MudTd>
<MudTd>
@AppIcons.EventEffort(context.Event)
@AppIcons.EventAttributes(context.Event)
</MudTd>
@{
var students
= context.Students
.OrderBy(s => s.EventRankings.Find(e => e.EventDefinition == context.Event)?.Rank ?? int.MaxValue)
.ThenByDescending(e => e.Grade)
.ThenBy(e => e.FirstName)
.ToArray();
}
@for (var i = 0; i <= _maxTeamSize; i++)
{
var student = i < students.Length ? students[i] : null;
if (student != null)
{
var rank = student.EventRankings
.Find(e => e.EventDefinition == context.Event)?.Rank ?? int.MaxValue;
<MudTd Class="@($"event-rank-{rank}")">
@student.Name
</MudTd>
}
else
{
<MudTd></MudTd>
}
}
<MudTd>
@if (context.Event.EventFormat == EventFormat.Team)
{
@if (context.Students.Count < context.Event.MinTeamSize)
{
<span>Min Team Size: @context.Event.MinTeamSize</span>
}
@if (context.Students.Count > context.Event.MaxTeamSize)
{
<span>Max Team Size: @context.Event.MaxTeamSize</span>
}
}
else if (context.Event.EventFormat == EventFormat.Individual
&& context.Students.Count > context.Event.MaxTeamCountState)
{
<span>Max Team Count State: @context.Event.MaxTeamCountState</span>
}
</MudTd>
</RowTemplate>
</MudTable>
</MudContainer>
<MudContainer Class="mt-3 mb-1 nobrk pagebreak">
<MudTable Items="_students">
<HeaderContent>
<MudTh>Student</MudTh>
<MudTh>Effort</MudTh>
@for (var i = 0; i <= 5; i++)
{
<MudTh></MudTh>
}
<MudTh></MudTh>
</HeaderContent>
<RowTemplate>
<MudTd>@context.Name</MudTd>
<MudTd>@context.Teams.Sum(e => e.Event.LevelOfEffort)</MudTd>
@{
var teams = context.Teams
.OrderBy(e =>
context.EventRankings.Find(ser => ser.EventDefinition == e.Event)?.Rank ?? int.MaxValue
).ToArray();
}
@for (var i = 0; i <= 5; i++)
{
var team = i < teams.Length ? teams[i] : null;
@if (team != null)
{
var rank = context.EventRankings
.Find(e => e.EventDefinition == team.Event)?.Rank ?? int.MaxValue;
<MudTh Class="@($"event-rank-{rank}")">
@team.ToString()
@AppIcons.EventEffort(team.Event)
@AppIcons.EventAttributes(team.Event)
@if (rank == int.MaxValue)
{
<span>❔</span>
}
</MudTh>
}
else
{
<MudTh></MudTh>
}
}
<MudTd>
@if (!context.Teams.Select(e => e.Event).Any(re => re.OnSiteActivity))
{
<span>No On-Site Activity</span>
}
@if (!context.Teams.Select(e => e.Event).Any(re => re.RegionalEvent))
{
<span>No Regional Event</span>
}
</MudTd>
</RowTemplate>
</MudTable>
</MudContainer>
<MudContainer Class="mt-3 mb-1 nobrk pagebreak">
<MudTable Items="_students">
<HeaderContent>
<MudTh>Student</MudTh>
<MudTh>Grade, TSA Year</MudTh>
<MudTh>Level of Effort</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd>@context.Name</MudTd>
<MudTd>@AppIcons.GetOrdinal(context.Grade), @context.TsaYear</MudTd>
<MudTd>@context.Teams.Sum(e => e.Event.LevelOfEffort)
@if (!context.Teams.Select(e => e.Event).Any(re => re.OnSiteActivity))
{
<span>No On-Site Activity</span>
}
@if (!context.Teams.Select(e => e.Event).Any(re => re.RegionalEvent))
{
<span>No Regional Event</span>
}
</MudTd>
</RowTemplate>
<ChildRowContent>
<MudTr>
<MudTable Items="@context.Teams.OrderBy(e =>
context.EventRankings.Find(ser => ser.EventDefinition == e.Event)?.Rank ?? int.MaxValue
)" Context="team">
<RowTemplate>
@{ var rank = context.EventRankings
.Find(e => e.EventDefinition == team.Event)?.Rank ?? int.MaxValue; }
<MudTd Class="@($"event-rank-{rank}")">
@team.ToString()
@AppIcons.EventEffort(team.Event)
@AppIcons.EventAttributes(team.Event)
@if (rank == int.MaxValue)
{
<span>❔</span>
}
</MudTd>
<MudTd>@string.Join(", ", team.Students.Where(e => e != context).Select(e => e.FirstName))</MudTd>
<MudTd></MudTd>
</RowTemplate>
</MudTable>
</MudTr>
</ChildRowContent>
</MudTable>
</MudContainer>
<MudContainer>
@foreach (var studentForEvents in _students)
{
<MudContainer Class="pagebreak">
<MudText Typo="Typo.h4">@studentForEvents.Name</MudText>
@foreach (var team in studentForEvents.Teams)
{
<MudContainer Class="mt-3 mb-1 nobrk">
<MudGrid>
<MudItem xs="6">
<MudStack>
<MudItem>
<MudText Class="d-flex py-1" Typo="Typo.h5">
@team.ToString()
</MudText>
</MudItem>
@if (team.Event.RegionalEvent)
{
<MudItem>
<MudText Class="d-flex" Typo="Typo.caption"><i>Regional Event</i></MudText>
</MudItem>
}
</MudStack>
</MudItem>
<MudItem xs="2">
<MudText>
<strong>@team.Event.EventFormat</strong>
</MudText>
</MudItem>
<MudItem xs="1">
<strong>Effort</strong>: @AppIcons.LevelOfEffortIcon(@team.Event.LevelOfEffort)
</MudItem>
<MudItem xs="3">
<strong>Activity</strong>: @team.Event.SemifinalistActivity
</MudItem>
@if (team.Event.EventFormat == EventFormat.Team)
{
<MudItem xs="12">
<MudText Class="d-flex py-1" Typo="Typo.h6">
Team Members: @string.Join(", ", team.Students.OrderByDescending(e => e.Grade + e.TsaYear).Select(e => e.FirstName))
</MudText>
</MudItem>
}
<MudItem xs="12">
<MudText Class="d-flex py-1" Style="white-space:pre-wrap;">@team.Event.Description</MudText>
</MudItem>
@if (!string.IsNullOrEmpty(team.Event.Theme))
{
<MudItem xs="3">
<MudText Class="d-flex py-1">
<i>Theme for 2025-26:</i>
</MudText>
</MudItem>
<MudItem xs="8">
<MudText Class="d-flex py-1" Style="white-space:pre-wrap;">@team.Event.Theme</MudText>
</MudItem>
}
@if (!string.IsNullOrEmpty(team.Event.Documentation))
{
<MudItem xs="3">
<MudText Class="d-flex py-1">
<i>Materials:</i>
</MudText>
</MudItem>
<MudItem xs="8">
<MudText Class="d-flex py-1" Style="white-space:pre-wrap;">@team.Event.Documentation</MudText>
</MudItem>
}
</MudGrid>
</MudContainer>
<MudDivider/>
}
</MudContainer>
}
</MudContainer>
}
@code {
private Team[]? _teams;
private int _maxTeamSize;
private Student[]? _students;
protected override async Task OnInitializedAsync()
{
_teams
= await Context.Teams
.Include(e => e.Event)
.Include(e => e.Students)
.OrderBy(e => e.Event.Name)
.ThenBy(e => e.Number)
.ToArrayAsync();
_maxTeamSize = _teams.Max(t => t.Students.Count);
_students =
await Context.Students
.Include(e => e.Teams)
.ThenInclude(e => e.Captain)
.Include(e => e.EventRankings)
.ThenInclude(e => e.EventDefinition)
.OrderBy(e => e.FirstName).ToArrayAsync();
}
}