@* ExportDialog — modal that collects a DateRange + ExportKind, then calls ExportToExcelUseCase. Reports back via DialogResult so the caller can show a snackbar with the file path. Keyboard: Esc to cancel, Enter to submit. *@ @using Marathon.Application.UseCases @using AppDateRange = Marathon.Application.Storage.DateRange @using ExportKind = Marathon.Application.Storage.ExportKind @inject IStringLocalizer L @inject ExportToExcelUseCase ExportUseCase @inject ILogger Logger @L["Export.Kicker"]

@L["Export.Title"]

@L["Export.Kind.PreMatch"] @L["Export.Kind.Live"] @L["Export.Kind.Combined"]
@if (_error is not null) { }
@L["Export.Cancel"] @if (_busy) { @L["Common.Loading"] } else { @L["Export.Submit"] }
@code { [CascadingParameter] private MudDialogInstance Dialog { get; set; } = default!; [Parameter] public DateTime? InitialFrom { get; set; } [Parameter] public DateTime? InitialTo { get; set; } [Parameter] public ExportKind InitialKind { get; set; } = ExportKind.Combined; private DateTime? _from; private DateTime? _to; private ExportKind _kind; private bool _busy; private string? _error; protected override void OnInitialized() { var moscow = MoscowTime.Now; _from = InitialFrom ?? moscow.AddDays(-1).Date; _to = InitialTo ?? moscow.AddDays(1).Date; _kind = InitialKind; } private void Cancel() => Dialog.Cancel(); private async Task Submit() { if (_from is null || _to is null) { _error = L["Export.Error.MissingDates"]; return; } if (_from > _to) { _error = L["Export.Error.InvalidRange"]; return; } _error = null; _busy = true; StateHasChanged(); try { // Use Moscow offset to match domain ScheduledAt invariant. var range = new AppDateRange( new DateTimeOffset(_from.Value.Date, MoscowTime.Offset), MoscowTime.EndOfMoscowDay(DateOnly.FromDateTime(_to.Value.Date))); var path = await ExportUseCase.ExecuteAsync(range, _kind, CancellationToken.None); Dialog.Close(DialogResult.Ok(path)); } catch (Exception ex) { Logger.LogError(ex, "Export failed"); _error = L["Export.Error.Failed"].Value + " — " + ex.Message; } finally { _busy = false; StateHasChanged(); } } private async Task HandleKeyDown(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs e) { if (e.Key == "Enter" && !_busy) { await Submit(); } else if (e.Key == "Escape") { Cancel(); } } }