Files
chapter-organizer/WebApp/Components/Features/Students/EventRanking.razor
T
poprhythm 5c1e0b7444 Update padding for MudPaper components across various features
Increased padding from 'pa-4' to 'pa-6' for MudPaper components in Events, MeetingSchedule, Students, and Teams features to ensure consistent styling and improved visual spacing.
2025-12-27 10:43:15 -05:00

161 lines
6.4 KiB
Plaintext

@page "/students/event-ranking"
@attribute [Authorize]
@using Microsoft.EntityFrameworkCore
@using WebApp.Models
@using Core.Validation
@inject AppDbContext Context
@inject ValidationService ValidationService
@rendermode InteractiveServer
<PageHeader
Title="Student Event Ranks"
Icon="@AppIcons.EventRank" />
@if (_students == null)
{
<p><em>Loading...</em></p>
}
else
{
<MudStack Spacing="4">
<MudPaper Elevation="2" Class="pa-6">
<MudText Typo="Typo.h5" Class="mb-4">Students by Rank</MudText>
<MudTable Items="_students" Hover="true" Striped="true" Breakpoint="Breakpoint.Sm" LoadingProgressColor="Color.Info">
<HeaderContent>
<MudTh>Name</MudTh>
<MudTh>Grade</MudTh>
<MudTh>TSA Year</MudTh>
<MudTh></MudTh>
<MudTh>Warnings</MudTh>
@for (var i = 1; i <= 10; i++)
{
var ii = i;
<MudTh>@AppIcons.GetOrdinal(ii)</MudTh>
}
</HeaderContent>
<RowTemplate>
<MudTd>@context.FirstName</MudTd>
<MudTh>@context.Grade</MudTh>
<MudTh>@context.TsaYear</MudTh>
<MudTd><MudButton StartIcon="@Icons.Material.Filled.TableChart" Href="@($"students/event-ranking-edit/{context.Id}")">Edit</MudButton></MudTd>
<MudTd>
<ValidationWarnings Warnings="@GetStudentWarnings(context)" />
</MudTd>
@for (var i = 1; i <= 10; i++)
{
var ii = i;
var st = context.EventRankings.FirstOrDefault(e => e.Rank == i);
<MudTd Class="@($"event-rank-{ii})")">
@if (st != null)
{
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<span style="@($"display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: {AppIcons.RankedEventColor(ii)}; flex-shrink: 0;")")></span>
<span>@st.EventDefinition.ShortName&nbsp;
<EventAttributes EventDefinition="@st.EventDefinition"></EventAttributes>
</span>
</MudStack>
}
</MudTd>
}
</RowTemplate>
</MudTable>
</MudPaper>
<MudPaper Elevation="2" Class="pa-6">
<MudText Typo="Typo.h5" Class="mb-4">Events by Student</MudText>
<MudTable Items="_eventStudentRankings" Hover="true" Striped="true" Breakpoint="Breakpoint.Sm" LoadingProgressColor="Color.Info">
<HeaderContent>
<MudTh>Event</MudTh>
<MudTh>Level of Effort</MudTh>
<MudTh>Individual</MudTh>
<MudTh>Regional</MudTh>
<MudTh>On-site Activity</MudTh>
<MudTh>Team Size</MudTh>
@for (var i = 0; i < _maxEventStudentRankings; i++)
{
var i1 = i + 1;
<MudTh>@i1</MudTh>
}
</HeaderContent>
<RowTemplate>
<MudTd>@context.Event.Name</MudTd>
<MudTd>@context.Event.LevelOfEffort</MudTd>
<MudTd>@if (context.Event.EventFormat == EventFormat.Individual) { <span>ⓘ</span> }</MudTd >
<MudTd>@if (context.Event.RegionalEvent) { <span>ⓡ</span> }</MudTd >
<MudTd>@if (context.Event.OnSiteActivity) { <span>ⓐ</span> }</MudTd >
<MudTd>[@context.Event.MinTeamSize-@context.Event.MaxTeamSize]</MudTd >
@for (var j = 0; j < _maxEventStudentRankings; j++)
{
var student = j < context.StudentRanking.Length ? context.StudentRanking[j] : null;
var eventClass = student != null ? $"event-rank-{student.Item2}" : "";
<MudTd Class="@eventClass">
@if (student != null)
{
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<span style="@($"display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: {AppIcons.RankedEventColor(student.Item2)}; flex-shrink: 0;")")></span>
@student.Item1.FirstName
</MudStack>
}
</MudTd>
}
</RowTemplate>
</MudTable>
</MudPaper>
</MudStack>
}
@code {
private Student[]? _students;
private class EventStudentRankings {
public required EventDefinition Event {get; set; }
public required Tuple<Student,int>[] StudentRanking { get; set; }
}
private EventStudentRankings[] _eventStudentRankings = null!;
private int _maxEventStudentRankings;
protected override async Task OnInitializedAsync()
{
_students =
await Context.Students
.Include(e => e.EventRankings)
.ThenInclude(e => e.EventDefinition)
.OrderBy(e => e.FirstName).ToArrayAsync();
_eventStudentRankings =
_students.SelectMany(s =>
s.EventRankings,
(student, ranking) => new { e = ranking.EventDefinition, a = Tuple.Create(student, ranking.Rank) }
)
.GroupBy(e => e.e)
.Select(e =>
new EventStudentRankings
{
Event = e.Key,
StudentRanking = e.Select(er => er.a).OrderBy(ser => ser.Item2).ThenByDescending(ser => ser.Item1.Grade + ser.Item1.TsaYear).ToArray()
})
.OrderBy(e => e.Event.Name)
.ToArray();
var events = await Context.Events.ToArrayAsync();
var remainingEvents =
events
.Where(e => _eventStudentRankings.All(est => est.Event.Id != e.Id))
.Select(e => new EventStudentRankings { Event = e, StudentRanking = Array.Empty<Tuple<Student, int>>() })
.OrderBy(e => e.Event.Name)
.ToArray();
_eventStudentRankings = _eventStudentRankings.Concat(remainingEvents).ToArray();
_maxEventStudentRankings = _eventStudentRankings.Max(esr => esr.StudentRanking.Length);
}
private List<ValidationWarning> GetStudentWarnings(Student student)
{
return ValidationService.ValidateStudentRankings(student, ValidationContext.StudentRanking);
}
}