121 lines
4.3 KiB
Plaintext
121 lines
4.3 KiB
Plaintext
@page "/"
|
|
@attribute [Authorize]
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using WebApp.Models
|
|
@inject IConfiguration Configuration
|
|
@inject AppDbContext Context
|
|
|
|
<PageTitle>@Configuration["ChapterSettings:Name"] - TSA Chapter Organizer</PageTitle>
|
|
|
|
<MudPaper Elevation="0" Class="mb-6">
|
|
<div class="d-flex flex-column align-center text-center mb-4">
|
|
<MudImage Fluid="true" Src="TCO_Title.png" Alt="TSA Chapter Organizer" Class="mb-4" Style="width: 100%; max-width: 600px; height: auto;" />
|
|
<MudHidden Breakpoint="Breakpoint.SmAndDown">
|
|
<MudText Typo="Typo.h3" Class="mb-2">
|
|
<strong>@Configuration["ChapterSettings:Name"]</strong>
|
|
</MudText>
|
|
</MudHidden>
|
|
<MudHidden Breakpoint="Breakpoint.MdAndUp">
|
|
<MudText Typo="Typo.h5" Class="mb-2">
|
|
<strong>@Configuration["ChapterSettings:Name"]</strong>
|
|
</MudText>
|
|
</MudHidden>
|
|
<MudText Typo="Typo.h6" Color="Color.Secondary">
|
|
@Configuration["ChapterSettings:CompetitionYear"] Competition Year
|
|
</MudText>
|
|
</div>
|
|
</MudPaper>
|
|
|
|
<MudGrid>
|
|
<!-- Events Card -->
|
|
<DashboardCard Icon="@AppIcons.Events"
|
|
Title="Events"
|
|
Count="@_eventCount"
|
|
Subtitle="Total Events"
|
|
Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")"
|
|
NavigateUrl="/events" />
|
|
|
|
<!-- Students Card -->
|
|
<DashboardCard Icon="@AppIcons.Student"
|
|
Title="Students"
|
|
Count="@_studentCount"
|
|
Subtitle="Active Students"
|
|
NavigateUrl="/students">
|
|
@if (!string.IsNullOrEmpty(_gradeDistribution) && _gradeDistribution != "No students yet")
|
|
{
|
|
<MudStack>
|
|
<MudText Typo="Typo.caption">@((MarkupString)_gradeDistribution)</MudText>
|
|
</MudStack>
|
|
}
|
|
else
|
|
{
|
|
<MudText Typo="Typo.caption" Class="mt-2">No students yet</MudText>
|
|
}
|
|
</DashboardCard>
|
|
|
|
<!-- Teams Card -->
|
|
<DashboardCard Icon="@AppIcons.Teams"
|
|
Title="Teams"
|
|
Count="@_teamCount"
|
|
Subtitle="Total Teams"
|
|
Caption="@($"{_groupTeamsCount} Team | {_individualTeamsCount} Individual")"
|
|
NavigateUrl="/teams" />
|
|
|
|
<!-- Meeting Schedule Card -->
|
|
<DashboardCard Icon="@AppIcons.Scheduler"
|
|
Title="Schedule"
|
|
Caption="Optimize meeting times"
|
|
NavigateUrl="/meeting-schedule" />
|
|
</MudGrid>
|
|
|
|
@code {
|
|
private int _eventCount;
|
|
private int _individualEventsCount;
|
|
private int _teamEventsCount;
|
|
private int _studentCount;
|
|
private string _gradeDistribution = "";
|
|
private int _teamCount;
|
|
private int _individualTeamsCount;
|
|
private int _groupTeamsCount;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await LoadStatistics();
|
|
}
|
|
|
|
private async Task LoadStatistics()
|
|
{
|
|
// Events statistics
|
|
var events = await Context.Events.ToListAsync();
|
|
_eventCount = events.Count();
|
|
_individualEventsCount = events.Count(e => e.EventFormat == EventFormat.Individual);
|
|
_teamEventsCount = events.Count(e => e.EventFormat == EventFormat.Team);
|
|
|
|
// Students statistics
|
|
_studentCount = await Context.Students.CountAsync();
|
|
|
|
// Grade distribution
|
|
var gradeGroups = await Context.Students
|
|
.GroupBy(s => s.Grade)
|
|
.Select(g => new { Grade = g.Key, Count = g.Count() })
|
|
.OrderBy(g => g.Grade)
|
|
.ToListAsync();
|
|
|
|
if (gradeGroups.Any())
|
|
{
|
|
_gradeDistribution = string.Join(" | ", gradeGroups.Select(g =>
|
|
$"<span style=\"white-space: nowrap\">{AppIcons.GetOrdinalSuperscript(g.Grade)}: <strong>{g.Count}</strong></span>"));
|
|
}
|
|
else
|
|
{
|
|
_gradeDistribution = "No students yet";
|
|
}
|
|
|
|
// Teams statistics
|
|
var contextTeams = await Context.Teams.ToListAsync();
|
|
_teamCount = contextTeams.Count;
|
|
_individualTeamsCount = contextTeams.Count(e => e.Event.EventFormat == EventFormat.Individual);
|
|
_groupTeamsCount = contextTeams.Count(e => e.Event.EventFormat == EventFormat.Team);
|
|
}
|
|
}
|