This commit introduces the CalendarService, which provides methods for retrieving all calendar items and upcoming events. The service is integrated into various components, including the Calendar and Home pages, enhancing the calendar functionality by allowing users to view upcoming events and meeting histories. Additionally, the Index.razor component is updated to parse query parameters for date selection, improving user experience. The layout of the MeetingHistoryDetailDialog and SaveMeetingHistoryDialog components is also refined for better organization and responsiveness. These changes collectively enhance the calendar feature and improve the overall user interface in managing events and meetings.
219 lines
6.8 KiB
Plaintext
219 lines
6.8 KiB
Plaintext
@page "/calendar"
|
|
@attribute [Authorize]
|
|
@using WebApp.Models
|
|
@using WebApp.Services
|
|
@using Heron.MudCalendar
|
|
@using Microsoft.Extensions.Logging
|
|
@using WebApp.Authentication
|
|
@inject ICalendarService CalendarService
|
|
@inject ILogger<Index> Logger
|
|
@inject IDialogService DialogService
|
|
|
|
<PageHeader Title="Event Calendar" Description="View competition schedules and event occurrences" Icon="@AppIcons.EventCalendar">
|
|
<ActionButtons>
|
|
<MudTooltip Text="Import">
|
|
<MudButton StartIcon="@Icons.Material.Filled.ImportExport" Href="calendar/event-occurrences/import" Variant="Variant.Filled" Color="Color.Primary">Import</MudButton>
|
|
</MudTooltip>
|
|
<AuthorizeView Roles="@AuthRoles.Administrator">
|
|
<MudTooltip Text="Admin">
|
|
<MudButton StartIcon="@Icons.Material.Filled.AdminPanelSettings" Href="calendar/admin" Variant="Variant.Outlined" Color="Color.Default">Admin</MudButton>
|
|
</MudTooltip>
|
|
</AuthorizeView>
|
|
<PageNoteButton PageIdentifier="Event Calendar" />
|
|
</ActionButtons>
|
|
</PageHeader>
|
|
|
|
<MudPaper Elevation="2" Class="pa-3 pa-md-6">
|
|
@if (_calendarItems == null)
|
|
{
|
|
<MudProgressLinear Indeterminate="true" />
|
|
<MudText>Loading calendar events...</MudText>
|
|
}
|
|
else
|
|
{
|
|
<MudStack Spacing="2">
|
|
|
|
<MudCalendar T="CalendarItemWrapper"
|
|
Items="_calendarItems"
|
|
@bind-View="_currentView"
|
|
@bind-CurrentDay="_calendarDate"
|
|
Class="event-calendar"
|
|
ItemClicked="OnItemClicked">
|
|
<MonthTemplate>
|
|
<MudTooltip Text="@GetEventTooltip(context)">
|
|
<div class="calendar-event-item">
|
|
@context.Text
|
|
</div>
|
|
</MudTooltip>
|
|
</MonthTemplate>
|
|
<WeekTemplate>
|
|
<MudTooltip Text="@GetEventTooltip(context)">
|
|
<div class="calendar-event-item">
|
|
@context.Text
|
|
</div>
|
|
</MudTooltip>
|
|
</WeekTemplate>
|
|
<DayTemplate>
|
|
<MudTooltip Text="@GetEventTooltip(context)">
|
|
<div class="calendar-event-item">
|
|
@context.Text
|
|
</div>
|
|
</MudTooltip>
|
|
</DayTemplate>
|
|
</MudCalendar>
|
|
</MudStack>
|
|
}
|
|
</MudPaper>
|
|
|
|
@code {
|
|
private List<CalendarItemWrapper>? _calendarItems;
|
|
private DateTime _calendarDate = DateTime.Today;
|
|
private CalendarView _currentView = CalendarView.Month;
|
|
|
|
[SupplyParameterFromQuery]
|
|
private string? Date { get; set; }
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
// Parse date from query parameter if provided
|
|
if (!string.IsNullOrEmpty(Date) && DateTime.TryParse(Date, out var parsedDate))
|
|
{
|
|
_calendarDate = parsedDate.Date;
|
|
}
|
|
|
|
await LoadCalendarEvents();
|
|
}
|
|
|
|
private async Task LoadCalendarEvents()
|
|
{
|
|
try
|
|
{
|
|
Logger.LogInformation("Loading calendar events");
|
|
_calendarItems = await CalendarService.GetAllCalendarItemsAsync();
|
|
Logger.LogInformation("Loaded {Count} calendar items", _calendarItems.Count);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError(ex, "Error loading calendar events");
|
|
_calendarItems = [];
|
|
}
|
|
finally
|
|
{
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private string GetEventTooltip(CalendarItemWrapper wrapper)
|
|
{
|
|
if (wrapper.ItemType == CalendarItemType.Event && wrapper.EventItem != null)
|
|
{
|
|
return GetEventTooltip(wrapper.EventItem);
|
|
}
|
|
else if (wrapper.ItemType == CalendarItemType.Meeting && wrapper.MeetingItem != null)
|
|
{
|
|
return GetMeetingTooltip(wrapper.MeetingItem);
|
|
}
|
|
return wrapper.Text;
|
|
}
|
|
|
|
private string GetEventTooltip(CalendarEventItem item)
|
|
{
|
|
List<string> parts = [];
|
|
|
|
if (!string.IsNullOrEmpty(item.EventDefinition?.Name))
|
|
{
|
|
parts.Add($"Event: {item.EventDefinition.Name}");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(item.EventOccurrenceData?.Name))
|
|
{
|
|
parts.Add($"Occurrence: {item.EventOccurrenceData.Name}");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(item.EventOccurrenceData?.Location))
|
|
{
|
|
parts.Add($"Location: {item.EventOccurrenceData.Location}");
|
|
}
|
|
|
|
if (item.EventOccurrenceData?.StartTime != null)
|
|
{
|
|
parts.Add($"Time: {item.EventOccurrenceData.StartTime:g}");
|
|
}
|
|
|
|
if (item.StudentFirstNames.Any())
|
|
{
|
|
parts.Add($"Students: {string.Join(", ", item.StudentFirstNames)}");
|
|
}
|
|
|
|
return string.Join("\n", parts);
|
|
}
|
|
|
|
private string GetMeetingTooltip(CalendarMeetingItem item)
|
|
{
|
|
if (item.MeetingHistoryData == null)
|
|
return "Team Meeting";
|
|
|
|
return $"Team Meeting\nDate: {item.MeetingHistoryData.MeetingDate:g}";
|
|
}
|
|
|
|
private async Task OnItemClicked(CalendarItemWrapper wrapper)
|
|
{
|
|
if (_calendarItems == null)
|
|
return;
|
|
|
|
if (wrapper.ItemType == CalendarItemType.Event && wrapper.EventItem != null)
|
|
{
|
|
await ShowEventDetails(wrapper.EventItem);
|
|
}
|
|
else if (wrapper.ItemType == CalendarItemType.Meeting && wrapper.MeetingItem != null)
|
|
{
|
|
await ShowMeetingDetails(wrapper.MeetingItem);
|
|
}
|
|
}
|
|
|
|
private async Task ShowEventDetails(CalendarEventItem item)
|
|
{
|
|
if (item.EventOccurrenceData == null) return;
|
|
|
|
var parameters = new DialogParameters
|
|
{
|
|
["EventOccurrence"] = item.EventOccurrenceData,
|
|
["EventDefinition"] = item.EventDefinition,
|
|
["StudentFirstNames"] = item.StudentFirstNames
|
|
};
|
|
|
|
var options = new DialogOptions
|
|
{
|
|
CloseOnEscapeKey = true,
|
|
CloseButton = true,
|
|
MaxWidth = MaxWidth.Medium,
|
|
FullWidth = true
|
|
};
|
|
|
|
await DialogService.ShowAsync<EventOccurrenceDetailsDialog>("Event Details", parameters, options);
|
|
}
|
|
|
|
private async Task ShowMeetingDetails(CalendarMeetingItem item)
|
|
{
|
|
if (item.MeetingHistoryData == null) return;
|
|
|
|
var parameters = new DialogParameters
|
|
{
|
|
["MeetingHistoryId"] = item.MeetingHistoryData.Id
|
|
};
|
|
|
|
var options = new DialogOptions
|
|
{
|
|
CloseOnEscapeKey = true,
|
|
CloseButton = true,
|
|
MaxWidth = MaxWidth.Large,
|
|
FullWidth = true
|
|
};
|
|
|
|
await DialogService.ShowAsync<MeetingHistoryDetailDialog>("Meeting Details", parameters, options);
|
|
}
|
|
}
|
|
|