137 lines
6.6 KiB
Plaintext
137 lines
6.6 KiB
Plaintext
@page "/teachers/questionaire-results"
|
|
@using Marten
|
|
@using Microsoft.AspNetCore.Authorization
|
|
@using Wollmilchsau.Models
|
|
@using Wollmilchsau.Services.Ldap
|
|
@attribute [Authorize(Roles = "ROLE_TEACHER,ROLE_ADMIN")]
|
|
@inject ILdapService LdapService
|
|
@inject IDocumentSession DocumentSession
|
|
|
|
<PageTitle>Questionnaire results</PageTitle>
|
|
|
|
<MudContainer MaxWidth="MaxWidth.Large" Class="mt-6 mb-6">
|
|
<MudText Typo="Typo.h3" GutterBottom="true">Questionnaire results</MudText>
|
|
<MudText Typo="Typo.body1" Class="mb-6">Eligible students and their submitted semester preferences.</MudText>
|
|
|
|
@if (isLoading)
|
|
{
|
|
<MudStack AlignItems="AlignItems.Center" Class="py-8">
|
|
<MudProgressCircular Color="Color.Primary" Indeterminate="true" />
|
|
<MudText>Loading questionnaire results...</MudText>
|
|
</MudStack>
|
|
}
|
|
else if (results.Count == 0)
|
|
{
|
|
<MudAlert Severity="Severity.Info">No eligible students were found.</MudAlert>
|
|
}
|
|
else
|
|
{
|
|
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Class="mb-4">
|
|
@CompletedCount of @results.Count eligible students have submitted their choices.
|
|
</MudAlert>
|
|
|
|
<MudStack Spacing="4">
|
|
@foreach (var classroom in results.GroupBy(result => result.Classroom).OrderBy(group => group.Key, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
<MudPaper Outlined="true" Class="pa-4">
|
|
<MudText Typo="Typo.h5" GutterBottom="true">@classroom.Key</MudText>
|
|
|
|
<MudStack Spacing="3">
|
|
@foreach (var result in classroom)
|
|
{
|
|
<MudPaper Elevation="0" Outlined="true" Class="pa-3">
|
|
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="mb-3">
|
|
<div>
|
|
<MudText Typo="Typo.h6">@result.DisplayName</MudText>
|
|
<MudText Typo="Typo.caption" Color="Color.Secondary">@result.Username</MudText>
|
|
</div>
|
|
<MudChip T="string" Color="@(result.Submission is null ? Color.Warning : Color.Success)" Variant="Variant.Filled" Size="Size.Small">
|
|
@(result.Submission is null ? "Not submitted" : "Submitted")
|
|
</MudChip>
|
|
</MudStack>
|
|
|
|
@if (result.Submission is null)
|
|
{
|
|
<MudText Color="Color.Secondary">This student has not made a choice yet.</MudText>
|
|
}
|
|
else
|
|
{
|
|
<MudText Typo="Typo.caption" Color="Color.Secondary" Class="mb-2">Last updated: @result.Submission.SubmittedAt.LocalDateTime.ToString("g")</MudText>
|
|
<MudGrid Spacing="2">
|
|
@for (var alternativeIndex = 0; alternativeIndex < result.Submission.Alternatives.Count; alternativeIndex++)
|
|
{
|
|
var currentAlternativeIndex = alternativeIndex;
|
|
var alternative = result.Submission.Alternatives[currentAlternativeIndex];
|
|
<MudItem xs="12" md="4">
|
|
<MudPaper Outlined="true" Class="pa-3 h-100">
|
|
<MudText Typo="Typo.subtitle2" GutterBottom="true">Alternative @(currentAlternativeIndex + 1)</MudText>
|
|
@for (var semesterIndex = 0; semesterIndex < alternative.Count; semesterIndex++)
|
|
{
|
|
<MudText Typo="Typo.body2">Semester @(semesterIndex + 1): @alternative[semesterIndex]</MudText>
|
|
}
|
|
</MudPaper>
|
|
</MudItem>
|
|
}
|
|
</MudGrid>
|
|
}
|
|
</MudPaper>
|
|
}
|
|
</MudStack>
|
|
</MudPaper>
|
|
}
|
|
</MudStack>
|
|
}
|
|
</MudContainer>
|
|
|
|
@code {
|
|
private IReadOnlyList<StudentQuestionnaireResult> results = [];
|
|
private bool isLoading = true;
|
|
|
|
private int CompletedCount => results.Count(result => result.Submission is not null);
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
var submissions = await DocumentSession.Query<QuestionnaireSubmission>().ToListAsync();
|
|
var submissionsByStudent = submissions
|
|
.GroupBy(submission => submission.StudentId, StringComparer.OrdinalIgnoreCase)
|
|
.ToDictionary(
|
|
group => group.Key,
|
|
group => group.OrderByDescending(submission => submission.SubmittedAt).First(),
|
|
StringComparer.OrdinalIgnoreCase);
|
|
var students = new List<LdapUser>();
|
|
|
|
await foreach (var user in LdapService.GetAllUsers())
|
|
{
|
|
if (user.Role == LdapUserRole.Student &&
|
|
Wollmilchsau.Store.QuestionnaireStore.QuestionnaireSubmissionPolicy.IsClassroomAllowed(user.Classroom))
|
|
{
|
|
students.Add(user);
|
|
}
|
|
}
|
|
|
|
results = students
|
|
.OrderBy(student => student.Classroom, StringComparer.OrdinalIgnoreCase)
|
|
.ThenBy(student => student.Surname, StringComparer.OrdinalIgnoreCase)
|
|
.ThenBy(student => student.GivenName, StringComparer.OrdinalIgnoreCase)
|
|
.Select(student => new StudentQuestionnaireResult(
|
|
student.Username,
|
|
student.Classroom!,
|
|
GetDisplayName(student),
|
|
submissionsByStudent.GetValueOrDefault(student.Username)))
|
|
.ToList();
|
|
isLoading = false;
|
|
}
|
|
|
|
private static string GetDisplayName(LdapUser student)
|
|
{
|
|
var displayName = string.Join(" ", new[] { student.GivenName, student.Surname }.Where(value => !string.IsNullOrWhiteSpace(value)));
|
|
return string.IsNullOrWhiteSpace(displayName) ? student.Username : displayName;
|
|
}
|
|
|
|
private sealed record StudentQuestionnaireResult(
|
|
string Username,
|
|
string Classroom,
|
|
string DisplayName,
|
|
QuestionnaireSubmission? Submission);
|
|
}
|