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 ?? [];
}
}