@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; } } }