using System.Globalization; using Elternbeirat.Contracts; using Elternbeirat.PocketBase; using Elternbeirat.Web.Shared; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Http; namespace Elternbeirat.Web.Features.Posts; public partial class PostDetail { private static readonly CultureInfo German = CultureInfo.GetCultureInfo("de-DE"); [LoggerMessage(Level = LogLevel.Warning, Message = "Could not load post '{slug}' from PocketBase.")] private static partial void LogLoadFailed(ILogger logger, string slug, Exception exception); [Parameter] public string Slug { get; set; } = string.Empty; [Inject] private PocketBaseClient PocketBase { get; set; } = default!; [Inject] private ILogger Logger { get; set; } = default!; [CascadingParameter] private HttpContext? HttpContext { get; set; } private Post? _post; // The post body rendered from Markdown to HTML, ready to emit as a // MarkupString in the markup. private MarkupString Body => (MarkupString)Markdown.ToHtml(_post?.Body); protected override async Task OnParametersSetAsync() { try { var posts = await PocketBase.GetPostsAsync(); _post = posts.FirstOrDefault( p => string.Equals(p.Slug, Slug, StringComparison.OrdinalIgnoreCase)); } catch (HttpRequestException ex) { // Source unreachable -> treat as "not found" rather than a 500. The // 404 branch below serves the friendly /not-found page. LogLoadFailed(Logger, Slug, ex); _post = null; } // Unknown slug (or unreachable source) -> 404, so // UseStatusCodePagesWithReExecute serves the /not-found page instead of an // empty 200 response. if (_post is null && HttpContext is not null) { HttpContext.Response.StatusCode = StatusCodes.Status404NotFound; } } }