Files
chapter-organizer/WebApp/Components/Pages/Home.razor
T
poprhythm c9ef169989 Refactor Calendar and Home components for improved navigation and user experience
Updated the Calendar component's route from "/event-calendar" to "/calendar" for clarity. Enhanced the Home component to provide dynamic content based on the presence of students and teams, introducing new sections for "Getting Started" and "Team Building". Improved the DashboardCard component to support emphasized styling for better visual hierarchy. Updated the navigation menu to reflect these changes and ensure a more intuitive user experience.
2025-12-27 22:01:41 -05:00

229 lines
8.6 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>
@if (!_hasStudents)
{
<!-- Getting Started: No students yet -->
<MudPaper Elevation="0" Class="mb-4">
<MudText Typo="Typo.h4" Color="Color.Primary">Getting Started</MudText>
<MudText Typo="Typo.body2" Color="Color.Secondary">Add your chapter's students to begin</MudText>
</MudPaper>
<MudGrid>
<DashboardCard Icon="@AppIcons.Student"
Title="Students"
Count="@_studentCount"
Subtitle="Add Students"
NavigateUrl="/students"
Emphasized="true">
<MudText Typo="Typo.caption" Class="mt-2">Import or add your chapter roster</MudText>
</DashboardCard>
<DashboardCard Icon="@AppIcons.Events"
Title="Events"
Count="@_eventCount"
Subtitle="Total Events"
Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")"
NavigateUrl="/events" />
</MudGrid>
}
else if (!_hasTeams)
{
<!-- Team Building: Students exist but no teams yet -->
<MudPaper Elevation="0" Class="mb-4">
<MudText Typo="Typo.h4" Color="Color.Primary">Team Building</MudText>
<MudText Typo="Typo.body2" Color="Color.Secondary">Collect event rankings and build your teams</MudText>
</MudPaper>
<MudGrid>
<DashboardCard Icon="@AppIcons.EventRank"
Title="Event Ranking"
Caption="Collect student event preferences"
NavigateUrl="/students/event-ranking"
Emphasized="true"/>
<DashboardCard Icon="@AppIcons.TeamAssignment"
Title="Team Assignment"
Caption="Build optimal teams"
NavigateUrl="/teams/assignment"
Emphasized="true"/>
</MudGrid>
<MudPaper Elevation="0" Class="my-4">
<MudText Typo="Typo.h4">Chapter Data</MudText>
</MudPaper>
<MudGrid>
<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>
}
</DashboardCard>
<DashboardCard Icon="@AppIcons.Events"
Title="Events"
Count="@_eventCount"
Subtitle="Total Events"
Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")"
NavigateUrl="/events" />
</MudGrid>
}
else
{
<!-- Normal view: Students and teams exist -->
<MudPaper Elevation="0" Class="mb-4">
<MudText Typo="Typo.h4">Scheduling</MudText>
</MudPaper>
<MudGrid>
<DashboardCard Icon="@AppIcons.Scheduler"
Title="Meeting Schedule"
Caption="Optimize meeting times"
NavigateUrl="/meeting-schedule"/>
<DashboardCard Icon="@Icons.Material.Filled.Event"
Title="Event Calendar"
Caption="Conference schedules"
NavigateUrl="/calendar"/>
</MudGrid>
<MudPaper Elevation="0" Class="my-4">
<MudText Typo="Typo.h4">Teams & Registration</MudText>
</MudPaper>
<MudGrid>
<DashboardCard Icon="@Icons.Material.Filled.AppRegistration"
Title="Registration"
Caption="View student registrations"
NavigateUrl="/students/teams"/>
<DashboardCard Icon="@AppIcons.Teams"
Title="Teams"
Count="@_teamCount"
Subtitle="Total Teams"
Caption="@($"{_groupTeamsCount} Team | {_individualTeamsCount} Individual")"
NavigateUrl="/teams" />
</MudGrid>
<MudPaper Elevation="0" Class="my-4">
<MudText Typo="Typo.h4">Team Building</MudText>
</MudPaper>
<MudGrid>
<DashboardCard Icon="@AppIcons.EventRank"
Title="Event Ranking"
Caption="Student event preferences"
NavigateUrl="/students/event-ranking"/>
<DashboardCard Icon="@AppIcons.TeamAssignment"
Title="Team Assignment"
Caption="Build optimal teams"
NavigateUrl="/teams/assignment"/>
</MudGrid>
<MudPaper Elevation="0" Class="my-4">
<MudText Typo="Typo.h4">Chapter Data</MudText>
</MudPaper>
<MudGrid>
<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>
}
</DashboardCard>
<DashboardCard Icon="@AppIcons.Events"
Title="Events"
Count="@_eventCount"
Subtitle="Total Events"
Caption="@($"{_teamEventsCount} Team | {_individualEventsCount} Individual")"
NavigateUrl="/events" />
</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;
private bool _hasStudents => _studentCount > 0;
private bool _hasTeams => _teamCount > 0;
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);
}
}