using Elternbeirat.Contracts; using Elternbeirat.PocketBase; using Elternbeirat.Web.Shared; using Microsoft.AspNetCore.Components; namespace Elternbeirat.Web.Features.Events; public partial class EventList { [LoggerMessage( Level = LogLevel.Error, Message = "Could not load events from PocketBase; content source is unavailable.")] private static partial void LogSourceUnavailable( ILogger logger, Exception exception); [Inject] private PocketBaseClient PocketBase { get; set; } = null!; [Inject] private ILogger Logger { get; set; } = null!; [CascadingParameter] private HttpContext? HttpContext { get; set; } // The "events" page record supplies the heading and intro text, so an editor // owns them in PocketBase like every other page, instead of them being // hard-coded here. Null until loaded, or when no such page exists. private Page? _page; private IReadOnlyList _upcomingEvents = []; private IReadOnlyList _pastEvents = []; // Set when the content source could not be reached or read. The markup then // shows a "temporarily unavailable" note instead of "no events", matching the // 503 this sets on the response. private bool _unavailable; // The page body rendered from Markdown to HTML, ready to emit as a MarkupString. private MarkupString Body => (MarkupString)Markdown.ToHtml(_page?.Body); protected override async Task OnInitializedAsync() { IReadOnlyList events; try { var token = HttpContext?.RequestAborted ?? CancellationToken.None; var pages = await PocketBase.GetPagesAsync(token); _page = pages.FirstOrDefault( page => string.Equals(page.Slug, "events", StringComparison.OrdinalIgnoreCase)); events = await PocketBase.GetEventsAsync(token); } catch (PocketBaseUnavailableException exception) { // Empty sections would claim there are no events. The site works, its // data store is down: 503 and an honest note. LogSourceUnavailable(Logger, exception); _unavailable = true; SourceUnavailable.SetStatus(HttpContext); return; } // Split into upcoming and past by date, so an event earlier today still // counts as upcoming. Upcoming earliest first, past most recent first. var today = DateOnly.FromDateTime(DateTime.Today); _upcomingEvents = [ .. events .Where(@event => DateOnly.FromDateTime(@event.Start) >= today) .OrderBy(@event => @event.Start) ]; _pastEvents = [ .. events .Where(@event => DateOnly.FromDateTime(@event.Start) < today) .OrderByDescending(@event => @event.Start) ]; } }