diff --git a/WebApp/Components/Pages/MeetingSchedulePages/Index.razor b/WebApp/Components/Pages/MeetingSchedulePages/Index.razor index 4adc53e..6f32c04 100644 --- a/WebApp/Components/Pages/MeetingSchedulePages/Index.razor +++ b/WebApp/Components/Pages/MeetingSchedulePages/Index.razor @@ -155,19 +155,10 @@ - Absent Students - - @foreach (var student in _students.OrderBy(e => e.FirstName)) - { - - @student.FirstNameLastName - - } - + diff --git a/WebApp/Components/Pages/TeamPages/Create.razor b/WebApp/Components/Pages/TeamPages/Create.razor index ee254a6..d91fd9b 100644 --- a/WebApp/Components/Pages/TeamPages/Create.razor +++ b/WebApp/Components/Pages/TeamPages/Create.razor @@ -15,18 +15,45 @@ - + @foreach (var evt in _events) { } - + @if (_existingTeams?.Count == 1) + { + + A team for @Team.Event.Name already exists. This will be team 2, and the existing team will become team 1. + + } + else if (_existingTeams?.Count >= 2) + { + + Two teams for @Team.Event.Name already exist. Cannot create a third team. + + } + + + + + + + + @if (!string.IsNullOrEmpty(_errorMessage)) + { + @_errorMessage + } Back Add @@ -36,6 +63,10 @@ private Team Team { get; set; } = new(); private List? _events; + private List _students = []; + private IEnumerable _selectedStudents = []; + private string? _errorMessage; + private List? _existingTeams; protected override async Task OnInitializedAsync() { @@ -43,13 +74,78 @@ await Context.Events .OrderBy(e => e.Name) .ToListAsync(); + + _students = await Context.Students.ToListAsync(); + } + + private async Task OnEventChanged(EventDefinition selectedEvent) + { + Team.Event = selectedEvent; + + // Clear any previous error messages + _errorMessage = null; + + // Get all existing teams for this event + _existingTeams = await Context.Teams + .Include(t => t.Event) + .Where(t => t.Event.Id == selectedEvent.Id) + .ToListAsync(); } private async Task AddTeam() { - Team.Identifier = Team.Event.Name; + // Clear previous error message + _errorMessage = null; + + // Get current count of teams for this event + var existingTeamCount = await Context.Teams + .CountAsync(t => t.Event.Id == Team.Event.Id); + + // Prohibit creation of third team + if (existingTeamCount >= 2) + { + _errorMessage = $"Cannot create a third team for {Team.Event.Name}. Maximum of 2 teams allowed."; + return; + } + + // Handle automatic numbering based on event format + if (Team.Event.EventFormat == EventFormat.Individual && _selectedStudents.Count() == 1) + { + // For individual events, use student's first name as identifier + var student = _selectedStudents.First(); + Team.Identifier = student.FirstName; + Team.Captain = student; + } + else if (existingTeamCount == 1) + { + // This is the second team - assign numbers + var existingTeam = await Context.Teams + .FirstOrDefaultAsync(t => t.Event.Id == Team.Event.Id); + + if (existingTeam != null) + { + // Update existing team to number 1 + existingTeam.Identifier = "1"; + Context.Teams.Update(existingTeam); + } + + // Set new team to number 2 + Team.Identifier = "2"; + } + else + { + // This is the first team - no number + Team.Identifier = null; + } + + // Add selected students to the team + foreach (var student in _selectedStudents) + { + Team.Students.Add(student); + } + Context.Teams.Add(Team); - + await Context.SaveChangesAsync(); NavigationManager.NavigateTo("/teams"); } diff --git a/WebApp/Components/Pages/TeamPages/Edit.razor b/WebApp/Components/Pages/TeamPages/Edit.razor index 2dd1646..b363788 100644 --- a/WebApp/Components/Pages/TeamPages/Edit.razor +++ b/WebApp/Components/Pages/TeamPages/Edit.razor @@ -20,28 +20,15 @@ else - - - @foreach (var student in _students.OrderBy(e => e.FirstName)) - { - @student.Name - } - - - Captain - - @foreach (var student in _selectedStudents.OrderBy(e => e.FirstName)) - { - - } - + + + - @@ -57,7 +44,7 @@ else [SupplyParameterFromForm] private Team? Team { get; set; } - private IEnumerable _selectedStudents = new HashSet(); + private IEnumerable _selectedStudents = []; private List _students = []; protected override async Task OnInitializedAsync() @@ -67,10 +54,7 @@ else .Include(e => e.Students) .FirstOrDefaultAsync(m => m.Id == Id); _students = await Context.Students.ToListAsync(); - foreach (var s in Team.Students) - { - ((HashSet)_selectedStudents).Add(s); - } + _selectedStudents = Team.Students.ToList(); if (Team is null) { @@ -89,7 +73,7 @@ else // To protect from overposting attacks, enable the specific properties you want to bind to. // For more information, see https://learn.microsoft.com/aspnet/core/blazor/forms/#mitigate-overposting-attacks. private async Task UpdateTeam() - { + { //Context.Attach(Team!).Entity = EntityState.Modified; Team.Students.Clear(); foreach (var s in _selectedStudents) @@ -97,6 +81,13 @@ else Team.Students.Add(s); } + // Update identifier for individual events + if (Team.Event.EventFormat == EventFormat.Individual && Team.Students.Count == 1) + { + Team.Captain ??= Team.Students[0]; + Team.Identifier = Team.Captain.FirstName; + } + try { await Context.SaveChangesAsync(); diff --git a/WebApp/Components/Pages/TeamPages/Index.razor b/WebApp/Components/Pages/TeamPages/Index.razor index dbb0ff0..73c836b 100644 --- a/WebApp/Components/Pages/TeamPages/Index.razor +++ b/WebApp/Components/Pages/TeamPages/Index.razor @@ -83,6 +83,20 @@ if (result == true) { + // If deleting a numbered team (1 or 2), clear the identifier of the remaining team + if (team.Identifier == "1" || team.Identifier == "2") + { + var remainingTeam = await Context.Teams + .Include(t => t.Event) + .FirstOrDefaultAsync(t => t.Event.Id == team.Event.Id && t.Id != team.Id); + + if (remainingTeam != null) + { + remainingTeam.Identifier = null; + Context.Teams.Update(remainingTeam); + } + } + Context.Teams.Remove(team!); await Context.SaveChangesAsync(); Snackbar.Add($"Delete event: Delete of Team {team}", Severity.Info); diff --git a/WebApp/Components/StudentToggleSelector.razor b/WebApp/Components/StudentToggleSelector.razor new file mode 100644 index 0000000..979ca71 --- /dev/null +++ b/WebApp/Components/StudentToggleSelector.razor @@ -0,0 +1,48 @@ +@if (Title != null) +{ + @Title +} + + + @foreach (var student in Students.OrderBy(e => e.FirstName)) + { + + @if (ShowFullName) + { + @student.FirstNameLastName + } + else + { + @student.FirstName + } + + } + + +@code { + [Parameter] + public IEnumerable Students { get; set; } = []; + + [Parameter] + public IEnumerable SelectedStudents { get; set; } = []; + + [Parameter] + public EventCallback> SelectedStudentsChanged { get; set; } + + [Parameter] + public string? Title { get; set; } + + [Parameter] + public bool ShowFullName { get; set; } = true; + + private async Task OnSelectedStudentsChanged(IEnumerable value) + { + SelectedStudents = value; + await SelectedStudentsChanged.InvokeAsync(value); + } +} diff --git a/WebApp/Components/TeamCaptainSelector.razor b/WebApp/Components/TeamCaptainSelector.razor new file mode 100644 index 0000000..eb435e2 --- /dev/null +++ b/WebApp/Components/TeamCaptainSelector.razor @@ -0,0 +1,38 @@ +@if (Title != null) +{ + @Title +} + + + @foreach (var student in Students.OrderBy(e => e.FirstName)) + { + + } + + +@code { + [Parameter] + public IEnumerable Students { get; set; } = []; + + [Parameter] + public Student? SelectedCaptain { get; set; } + + [Parameter] + public EventCallback SelectedCaptainChanged { get; set; } + + [Parameter] + public string? Title { get; set; } = "Captain"; + + [Parameter] + public Typo TitleTypo { get; set; } = Typo.body1; + + private async Task OnSelectedCaptainChanged(Student? value) + { + SelectedCaptain = value; + await SelectedCaptainChanged.InvokeAsync(value); + } +}