using System.Net.Http.Json; using System.Text.Json; using Elternbeirat.Contracts; namespace Elternbeirat.PocketBase; /// /// Reads published content from a PocketBase instance over its REST API. /// /// One method per collection (pages, posts, events, faqs). Each returns only /// records with public = true and lets PocketBase do the filtering and /// sorting via query parameters. The is expected to have /// its set to the PocketBase base URL, so it /// is registered as a typed client via AddHttpClient. /// /// public sealed class PocketBaseClient(HttpClient http) { private static readonly JsonSerializerOptions JsonOptions = CreateJsonOptions(); private static JsonSerializerOptions CreateJsonOptions() { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, }; options.Converters.Add(new LocalDateTimeConverter()); options.Converters.Add(new NullableLocalDateTimeConverter()); return options; } /// Gets all public pages, ordered for navigation. public Task> GetPagesAsync(CancellationToken ct = default) => GetRecordsAsync("pages", "order", ct); /// Gets all public posts, newest first. public Task> GetPostsAsync(CancellationToken ct = default) => GetRecordsAsync("posts", "-date", ct); /// Gets all public events, earliest start first. public Task> GetEventsAsync(CancellationToken ct = default) => GetRecordsAsync("events", "start", ct); /// Gets all public FAQ entries. public Task> GetFaqsAsync(CancellationToken ct = default) => GetRecordsAsync("faqs", "topic", ct); private async Task> GetRecordsAsync(string collection, string sort, CancellationToken ct) { // filter=public=true keeps drafts out; perPage is large enough to fetch // every record in a single page given the small content volume. var url = $"/api/collections/{collection}/records" + $"?perPage=500&filter={Uri.EscapeDataString("public=true")}" + $"&sort={Uri.EscapeDataString(sort)}"; var result = await http.GetFromJsonAsync>(url, JsonOptions, ct); return result?.Items ?? []; } }