@page "/calendar/admin"
@attribute [Authorize(Roles = AuthRoles.Administrator)]
@using Core.Entities
@using Microsoft.EntityFrameworkCore
@using WebApp.Components.Shared.Components
@using WebApp.Authentication
@using MudBlazor
@inject AppDbContext Context
@inject ISnackbar Snackbar
@inject IDialogService DialogService
Statistics
@if (_statistics == null)
{
Loading statistics...
}
else
{
Total Occurrences: @_statistics.TotalCount
@if (_statistics.TotalCount > 0)
{
Date Range: @_statistics.EarliestDate.ToString("MMM dd, yyyy") - @_statistics.LatestDate.ToString("MMM dd, yyyy")
Unique Dates: @_statistics.UniqueDateCount
Events with Occurrences: @_statistics.EventDefinitionCount
Special Events: @_statistics.SpecialEventCount
@if (_statistics.DuplicateCount > 0)
{
Found @_statistics.DuplicateCount potential duplicate occurrence(s)
}
}
else
{
No event occurrences in database
}
}
Delete by Date Range
Delete Occurrences in Range
@if (_isDeleting)
{
Deleting occurrences...
}
@code {
private CalendarStatistics? _statistics;
private DateTime? _deleteStartDate;
private DateTime? _deleteEndDate;
private bool _isDeleting = false;
protected override async Task OnInitializedAsync()
{
await LoadStatistics();
}
private async Task LoadStatistics()
{
try
{
var occurrences = await Context.EventOccurrences
.Include(eo => eo.EventDefinition)
.ToListAsync();
_statistics = new CalendarStatistics
{
TotalCount = occurrences.Count,
EarliestDate = occurrences.Any() ? occurrences.Min(eo => eo.StartTime.Date) : DateTime.Today,
LatestDate = occurrences.Any() ? occurrences.Max(eo => eo.StartTime.Date) : DateTime.Today,
UniqueDateCount = occurrences.Select(eo => eo.StartTime.Date).Distinct().Count(),
EventDefinitionCount = occurrences.Where(eo => eo.EventDefinitionId.HasValue).Select(eo => eo.EventDefinitionId).Distinct().Count(),
SpecialEventCount = occurrences.Where(eo => !string.IsNullOrEmpty(eo.SpecialEventType)).Count(),
DuplicateCount = CountDuplicates(occurrences)
};
}
catch (Exception ex)
{
Snackbar.Add($"Error loading statistics: {ex.Message}", Severity.Error);
_statistics = new CalendarStatistics();
}
}
private int CountDuplicates(List occurrences)
{
// Count occurrences that have the same name, date, time, and location
return occurrences
.GroupBy(eo => new
{
eo.Name,
Date = eo.StartTime.Date,
Time = eo.Time,
eo.Location,
eo.EventDefinitionId,
eo.SpecialEventType
})
.Where(g => g.Count() > 1)
.Sum(g => g.Count() - 1); // Count duplicates (total - 1 per group)
}
private async Task HandleDeleteByDateRange()
{
if (_deleteStartDate == null || _deleteEndDate == null)
{
Snackbar.Add("Please select both start and end dates", Severity.Warning);
return;
}
if (_deleteStartDate > _deleteEndDate)
{
Snackbar.Add("Start date must be before end date", Severity.Warning);
return;
}
// Count occurrences that will be deleted
var countToDelete = await Context.EventOccurrences
.Where(eo => eo.StartTime.Date >= _deleteStartDate.Value.Date &&
eo.StartTime.Date <= _deleteEndDate.Value.Date)
.CountAsync();
if (countToDelete == 0)
{
Snackbar.Add("No occurrences found in the specified date range", Severity.Info);
return;
}
// Confirm deletion
var result = await DialogService.ShowMessageBox(
"Confirm Deletion",
$"Are you sure you want to delete {countToDelete} occurrence(s) from {_deleteStartDate.Value:MMM dd, yyyy} to {_deleteEndDate.Value:MMM dd, yyyy}? This action cannot be undone.",
yesText: "Delete",
noText: "Cancel");
if (result == true)
{
_isDeleting = true;
try
{
var occurrencesToDelete = await Context.EventOccurrences
.Where(eo => eo.StartTime.Date >= _deleteStartDate.Value.Date &&
eo.StartTime.Date <= _deleteEndDate.Value.Date)
.ToListAsync();
Context.EventOccurrences.RemoveRange(occurrencesToDelete);
await Context.SaveChangesAsync();
Snackbar.Add($"Successfully deleted {occurrencesToDelete.Count} occurrence(s)", Severity.Success);
// Reload statistics
await LoadStatistics();
// Clear date pickers
_deleteStartDate = null;
_deleteEndDate = null;
}
catch (Exception ex)
{
Snackbar.Add($"Error deleting occurrences: {ex.Message}", Severity.Error);
}
finally
{
_isDeleting = false;
}
}
}
private class CalendarStatistics
{
public int TotalCount { get; set; }
public DateTime EarliestDate { get; set; }
public DateTime LatestDate { get; set; }
public int UniqueDateCount { get; set; }
public int EventDefinitionCount { get; set; }
public int SpecialEventCount { get; set; }
public int DuplicateCount { get; set; }
}
}