Fix/pocketbase date timezone #33
No files matched your search
@@ -42,11 +42,16 @@ public record Faq
|
|||||||
public required string Answer { get; init; }
|
public required string Answer { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the topic the question is grouped under, e.g. <c>"mensa"</c>.
|
/// Gets the topic the question is grouped under, e.g.
|
||||||
|
/// <c>"Mensa und Mittagessen"</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <see langword="required"/>: the FAQ page groups entries by topic, so an entry
|
/// <see langword="required"/>: the FAQ page groups entries by topic, so an entry
|
||||||
/// without one has no place. The field is required in PocketBase.
|
/// without one has no place. The field is required in PocketBase.
|
||||||
|
///
|
||||||
|
/// This is the heading shown on the page verbatim, not a slug: editors add a
|
||||||
|
/// new group by typing its heading here, no code change. Entries with the same
|
||||||
|
/// topic text land in one group.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonPropertyName("topic")]
|
[JsonPropertyName("topic")]
|
||||||
public required string Topic { get; init; }
|
public required string Topic { get; init; }
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public sealed class PocketBaseClientTests(PocketBaseFixture pocketBase)
|
|||||||
|
|
||||||
var faqs = await client.GetFaqsAsync();
|
var faqs = await client.GetFaqsAsync();
|
||||||
|
|
||||||
faqs.Select(f => f.Topic).ShouldBe(["mensa", "schliessfach"], ignoreOrder: true);
|
faqs.Select(f => f.Topic).ShouldBe(["Mensa und Mittagessen", "Schließfächer"], ignoreOrder: true);
|
||||||
faqs.ShouldAllBe(f => !string.IsNullOrWhiteSpace(f.Question));
|
faqs.ShouldAllBe(f => !string.IsNullOrWhiteSpace(f.Question));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,12 +317,12 @@ public sealed class PocketBaseFixture : IAsyncLifetime
|
|||||||
await CreateRecordAsync(http, "faqs", new
|
await CreateRecordAsync(http, "faqs", new
|
||||||
{
|
{
|
||||||
question = "Wann gibt es Mittagessen?", answer = "Um 12 Uhr.",
|
question = "Wann gibt es Mittagessen?", answer = "Um 12 Uhr.",
|
||||||
topic = "mensa", @public = true,
|
topic = "Mensa und Mittagessen", @public = true,
|
||||||
});
|
});
|
||||||
await CreateRecordAsync(http, "faqs", new
|
await CreateRecordAsync(http, "faqs", new
|
||||||
{
|
{
|
||||||
question = "Wie viel kostet ein Schließfach?", answer = "20 Euro.",
|
question = "Wie viel kostet ein Schließfach?", answer = "20 Euro.",
|
||||||
topic = "schliessfach", @public = true,
|
topic = "Schließfächer", @public = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ else
|
|||||||
@foreach (var group in _groups)
|
@foreach (var group in _groups)
|
||||||
{
|
{
|
||||||
<section class="faq-topic">
|
<section class="faq-topic">
|
||||||
<h2>@TopicLabel(group.Key)</h2>
|
<h2>@group.Key</h2>
|
||||||
@foreach (var faq in group)
|
@foreach (var faq in group)
|
||||||
{
|
{
|
||||||
<details class="faq-item">
|
<details class="faq-item">
|
||||||
|
|||||||
@@ -14,17 +14,6 @@ public partial class FaqList
|
|||||||
ILogger logger,
|
ILogger logger,
|
||||||
Exception exception);
|
Exception exception);
|
||||||
|
|
||||||
// German heading per topic. Unknown topics fall back to the raw key so a new
|
|
||||||
// topic in PocketBase still shows up rather than being silently dropped.
|
|
||||||
private static readonly Dictionary<string, string> TopicLabels =
|
|
||||||
new(StringComparer.Ordinal)
|
|
||||||
{
|
|
||||||
["mensa"] = "Mensa und Mittagessen",
|
|
||||||
["schliessfach"] = "Schließfächer",
|
|
||||||
["elterneuro"] = "Eltern-Euro",
|
|
||||||
["elternarbeit"] = "Elternarbeit und Mitmachen",
|
|
||||||
};
|
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private PocketBaseClient PocketBase { get; set; } = null!;
|
private PocketBaseClient PocketBase { get; set; } = null!;
|
||||||
|
|
||||||
@@ -57,7 +46,4 @@ public partial class FaqList
|
|||||||
SourceUnavailable.SetStatus(HttpContext);
|
SourceUnavailable.SetStatus(HttpContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string TopicLabel(string topic)
|
|
||||||
=> TopicLabels.GetValueOrDefault(topic, topic);
|
|
||||||
}
|
}
|
||||||
+9
-4
@@ -164,10 +164,15 @@ ihrer Kalender-App abonnieren — der Feed entsteht aus denselben Records.
|
|||||||
|
|
||||||
## Häufige Fragen (`faqs`)
|
## Häufige Fragen (`faqs`)
|
||||||
|
|
||||||
Eine Frage hat `question`, `answer` (Markdown), `topic` (eines von
|
Eine Frage hat `question`, `answer` (Markdown), `topic` und `public`. Die App
|
||||||
`mensa`/`schliessfach`/`elterneuro`/`elternarbeit`) und `public`. Die App baut
|
baut die FAQ-Seite generiert: sie gruppiert die Fragen nach `topic` und zeigt den
|
||||||
die FAQ-Seite generiert: sie gruppiert die Fragen nach `topic`. Der Rahmentext
|
`topic`-Text unverändert als Gruppen-Überschrift. `topic` ist also **keine feste
|
||||||
oben auf `/faqs` ist eine eigene Seite in `pages` (Slug `faqs`).
|
Auswahl**, sondern der Überschriftentext selbst (z. B. `Mensa und Mittagessen`) —
|
||||||
|
eine neue Gruppe entsteht einfach, indem eine Frage einen neuen `topic`-Text
|
||||||
|
bekommt; Fragen mit gleichem `topic` landen in derselben Gruppe. Auf Groß-/
|
||||||
|
Kleinschreibung und Leerzeichen achten, sonst entstehen versehentlich zwei
|
||||||
|
Gruppen. Der Rahmentext oben auf `/faqs` ist eine eigene Seite in `pages`
|
||||||
|
(Slug `faqs`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ migrate((app) => {
|
|||||||
,
|
,
|
||||||
events: [{"end":"","location":"Aula","note":"Gäste sind willkommen. Um Anmeldung im Sekretariat wird gebeten.","public":true,"start":"2026-10-08 19:30:00.000Z","title":"Elternbeiratssitzung"},{"end":"2026-10-20 18:30:00.000Z","location":"Klassenräume","note":"Terminvergabe über das Schulportal.","public":true,"start":"2026-10-20 16:00:00.000Z","title":"Elternsprechtag"},{"end":"2026-11-22 13:00:00.000Z","location":"Schulhof","note":"Kuchenspenden willkommen.","public":true,"start":"2026-11-22 09:00:00.000Z","title":"Herbstbasar"},{"end":"2027-01-06 00:00:00.000Z","location":"","note":"","public":true,"start":"2026-12-19 00:00:00.000Z","title":"Weihnachtsferien"},{"end":"","location":"Mensa","note":"Kennenlernen bei Butterbrezeln und Kaffee.","public":true,"start":"2026-09-10 18:00:00.000Z","title":"Willkommensabend der neuen Fünftklässler"}]
|
events: [{"end":"","location":"Aula","note":"Gäste sind willkommen. Um Anmeldung im Sekretariat wird gebeten.","public":true,"start":"2026-10-08 19:30:00.000Z","title":"Elternbeiratssitzung"},{"end":"2026-10-20 18:30:00.000Z","location":"Klassenräume","note":"Terminvergabe über das Schulportal.","public":true,"start":"2026-10-20 16:00:00.000Z","title":"Elternsprechtag"},{"end":"2026-11-22 13:00:00.000Z","location":"Schulhof","note":"Kuchenspenden willkommen.","public":true,"start":"2026-11-22 09:00:00.000Z","title":"Herbstbasar"},{"end":"2027-01-06 00:00:00.000Z","location":"","note":"","public":true,"start":"2026-12-19 00:00:00.000Z","title":"Weihnachtsferien"},{"end":"","location":"Mensa","note":"Kennenlernen bei Butterbrezeln und Kaffee.","public":true,"start":"2026-09-10 18:00:00.000Z","title":"Willkommensabend der neuen Fünftklässler"}]
|
||||||
,
|
,
|
||||||
faqs: [{"answer":"Die Anmeldung läuft über das Bestellsystem der Schule. Die Zugangsdaten erhalten Sie zu Schuljahresbeginn über die Klassenleitung.","public":true,"question":"Wie melde ich mein Kind zum Mittagessen an?","topic":"mensa"},{"answer":"Ein Mittagessen kostet aktuell **4,20 €**. Für Familien mit Anspruch auf Leistungen nach dem Bildungs- und Teilhabepaket ist das Essen kostenfrei – sprechen Sie das Sekretariat an.","public":true,"question":"Was kostet ein Mittagessen?","topic":"mensa"},{"answer":"Ja, täglich steht mindestens ein vegetarisches Gericht zur Wahl.","public":true,"question":"Gibt es vegetarische Gerichte?","topic":"mensa"},{"answer":"Schließfächer werden über einen externen Anbieter gemietet. Das Anmeldeformular liegt bei den [Downloads](/downloads).","public":true,"question":"Wie bekommt mein Kind ein Schließfach?","topic":"schliessfach"},{"answer":"Die Miete beträgt rund 15 € pro Schuljahr zuzüglich einer Kaution, die bei Rückgabe erstattet wird.","public":true,"question":"Was kostet die Miete?","topic":"schliessfach"},{"answer":"Wenden Sie sich an den Anbieter; die Kontaktdaten stehen auf dem Mietvertrag. Bei Fragen hilft auch der [Elternbeirat](/contact).","public":true,"question":"Der Schlüssel ist verloren – was nun?","topic":"schliessfach"},{"answer":"Der Eltern-Euro ist ein **freiwilliger** Beitrag, mit dem kleinere Anschaffungen für die Klassen unkompliziert finanziert werden – etwa Bastelmaterial oder Ausflüge.","public":true,"question":"Was ist der Eltern-Euro?","topic":"elterneuro"},{"answer":"Nein. Der Beitrag ist ausdrücklich freiwillig, und niemand wird bei Nichtzahlung benachteiligt.","public":true,"question":"Ist der Beitrag verpflichtend?","topic":"elterneuro"},{"answer":"Ob Schulfest, Basar oder eine helfende Hand bei Ausflügen – über jede Unterstützung freuen wir uns. Melden Sie sich einfach über die [Kontaktseite](/contact).","public":true,"question":"Wie kann ich mich engagieren?","topic":"elternarbeit"},{"answer":"Nein. Viele Aufgaben erledigen Eltern, die einfach mithelfen möchten, ganz ohne Amt.","public":true,"question":"Muss ich in den Elternbeirat gewählt sein, um zu helfen?","topic":"elternarbeit"}]
|
faqs: [{"answer":"Die Anmeldung läuft über das Bestellsystem der Schule. Die Zugangsdaten erhalten Sie zu Schuljahresbeginn über die Klassenleitung.","public":true,"question":"Wie melde ich mein Kind zum Mittagessen an?","topic":"Mensa und Mittagessen"},{"answer":"Ein Mittagessen kostet aktuell **4,20 €**. Für Familien mit Anspruch auf Leistungen nach dem Bildungs- und Teilhabepaket ist das Essen kostenfrei – sprechen Sie das Sekretariat an.","public":true,"question":"Was kostet ein Mittagessen?","topic":"Mensa und Mittagessen"},{"answer":"Ja, täglich steht mindestens ein vegetarisches Gericht zur Wahl.","public":true,"question":"Gibt es vegetarische Gerichte?","topic":"Mensa und Mittagessen"},{"answer":"Schließfächer werden über einen externen Anbieter gemietet. Das Anmeldeformular liegt bei den [Downloads](/downloads).","public":true,"question":"Wie bekommt mein Kind ein Schließfach?","topic":"Schließfächer"},{"answer":"Die Miete beträgt rund 15 € pro Schuljahr zuzüglich einer Kaution, die bei Rückgabe erstattet wird.","public":true,"question":"Was kostet die Miete?","topic":"Schließfächer"},{"answer":"Wenden Sie sich an den Anbieter; die Kontaktdaten stehen auf dem Mietvertrag. Bei Fragen hilft auch der [Elternbeirat](/contact).","public":true,"question":"Der Schlüssel ist verloren – was nun?","topic":"Schließfächer"},{"answer":"Der Eltern-Euro ist ein **freiwilliger** Beitrag, mit dem kleinere Anschaffungen für die Klassen unkompliziert finanziert werden – etwa Bastelmaterial oder Ausflüge.","public":true,"question":"Was ist der Eltern-Euro?","topic":"Eltern-Euro"},{"answer":"Nein. Der Beitrag ist ausdrücklich freiwillig, und niemand wird bei Nichtzahlung benachteiligt.","public":true,"question":"Ist der Beitrag verpflichtend?","topic":"Eltern-Euro"},{"answer":"Ob Schulfest, Basar oder eine helfende Hand bei Ausflügen – über jede Unterstützung freuen wir uns. Melden Sie sich einfach über die [Kontaktseite](/contact).","public":true,"question":"Wie kann ich mich engagieren?","topic":"Elternarbeit und Mitmachen"},{"answer":"Nein. Viele Aufgaben erledigen Eltern, die einfach mithelfen möchten, ganz ohne Amt.","public":true,"question":"Muss ich in den Elternbeirat gewählt sein, um zu helfen?","topic":"Elternarbeit und Mitmachen"}]
|
||||||
,
|
,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -393,21 +393,19 @@
|
|||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"autogeneratePattern": "",
|
||||||
"help": "",
|
"help": "",
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"id": "select2638274075",
|
"id": "select2638274075",
|
||||||
"maxSelect": 1,
|
"max": 0,
|
||||||
|
"min": 0,
|
||||||
"name": "topic",
|
"name": "topic",
|
||||||
|
"pattern": "",
|
||||||
"presentable": false,
|
"presentable": false,
|
||||||
|
"primaryKey": false,
|
||||||
"required": true,
|
"required": true,
|
||||||
"system": false,
|
"system": false,
|
||||||
"type": "select",
|
"type": "text"
|
||||||
"values": [
|
|
||||||
"mensa",
|
|
||||||
"schliessfach",
|
|
||||||
"elterneuro",
|
|
||||||
"elternarbeit"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"help": "",
|
"help": "",
|
||||||
|
|||||||
Reference in new issue
Block a user