Improve home page layout
This commit is contained in:
@@ -1,14 +1,107 @@
|
||||
@page "/"
|
||||
@page "/"
|
||||
@attribute [Authorize]
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using WebApp.Models
|
||||
@inject IConfiguration Configuration
|
||||
@inject AppDbContext Context
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
<PageTitle>@Configuration["ChapterSettings:Name"] - TSA Chapter Organizer</PageTitle>
|
||||
|
||||
<MudImage Fluid="true" Src="TCO_Title.png" Alt="TSA Chapter Organizer"></MudImage>
|
||||
<MudText Typo="Typo.h3">@Configuration["ChapterSettings:Name"]</MudText>
|
||||
<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="max-width: 600px;" />
|
||||
<MudText Typo="Typo.h3" Class="mb-2">
|
||||
<strong>@Configuration["ChapterSettings:Name"]</strong>
|
||||
</MudText>
|
||||
<MudText Typo="Typo.h6" Color="Color.Secondary">
|
||||
@Configuration["ChapterSettings:CompetitionYear"] Competition Year
|
||||
</MudText>
|
||||
</div>
|
||||
</MudPaper>
|
||||
|
||||
<MudLink Href="events">
|
||||
<MudCard>
|
||||
<MudCardHeader>Events</MudCardHeader>
|
||||
</MudCard>
|
||||
</MudLink>
|
||||
<MudGrid>
|
||||
<!-- Events Card -->
|
||||
<DashboardCard Icon="@AppIcons.Events"
|
||||
Title="Events"
|
||||
Count="@_eventCount"
|
||||
Subtitle="Total Events"
|
||||
Caption="@($"{_individualEventsCount} Individual | {_teamEventsCount} Team")"
|
||||
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"
|
||||
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;
|
||||
|
||||
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
|
||||
_teamCount = await Context.Teams.CountAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
@using Microsoft.AspNetCore.Components
|
||||
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudCard Elevation="4" Class="pa-4" Style="cursor: pointer; height: 100%;" @onclick="HandleClick">
|
||||
<MudCardContent>
|
||||
<div class="d-flex align-center mb-2">
|
||||
<MudIcon Icon="@Icon" Size="Size.Large" Class="mr-2" />
|
||||
<MudText Typo="Typo.h5">@Title</MudText>
|
||||
</div>
|
||||
<MudDivider Class="mb-3" />
|
||||
@if (Count != null)
|
||||
{
|
||||
<MudText Typo="Typo.h3" Color="Color.Info">@Count</MudText>
|
||||
<MudText Typo="Typo.body2">@Subtitle</MudText>
|
||||
}
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(Caption))
|
||||
{
|
||||
<MudText Typo="Typo.caption" Class="mt-2">@Caption</MudText>
|
||||
}
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
</MudItem>
|
||||
|
||||
@code {
|
||||
[Parameter] public string Icon { get; set; } = string.Empty;
|
||||
[Parameter] public string Title { get; set; } = string.Empty;
|
||||
[Parameter] public int? Count { get; set; }
|
||||
[Parameter] public string? Subtitle { get; set; } = string.Empty;
|
||||
[Parameter] public string? Caption { get; set; }
|
||||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
||||
[Parameter] public string NavigateUrl { get; set; } = string.Empty;
|
||||
[Inject] private NavigationManager Navigation { get; set; } = default!;
|
||||
|
||||
private void HandleClick()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(NavigateUrl))
|
||||
{
|
||||
Navigation.NavigateTo(NavigateUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user