diff --git a/Elternbeirat.Contracts/Faq.cs b/Elternbeirat.Contracts/Faq.cs
index f95f388..c7b22ca 100644
--- a/Elternbeirat.Contracts/Faq.cs
+++ b/Elternbeirat.Contracts/Faq.cs
@@ -42,11 +42,16 @@ public record Faq
public required string Answer { get; init; }
///
- /// Gets the topic the question is grouped under, e.g. "mensa".
+ /// Gets the topic the question is grouped under, e.g.
+ /// "Mensa und Mittagessen".
///
///
/// : the FAQ page groups entries by topic, so an entry
/// 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.
///
[JsonPropertyName("topic")]
public required string Topic { get; init; }
diff --git a/Elternbeirat.Web.Tests/PocketBaseClientTests.cs b/Elternbeirat.Web.Tests/PocketBaseClientTests.cs
index c8bc2ba..59b1305 100644
--- a/Elternbeirat.Web.Tests/PocketBaseClientTests.cs
+++ b/Elternbeirat.Web.Tests/PocketBaseClientTests.cs
@@ -111,7 +111,7 @@ public sealed class PocketBaseClientTests(PocketBaseFixture pocketBase)
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));
}
}
diff --git a/Elternbeirat.Web.Tests/PocketBaseFixture.cs b/Elternbeirat.Web.Tests/PocketBaseFixture.cs
index 3f4bc47..6d58445 100644
--- a/Elternbeirat.Web.Tests/PocketBaseFixture.cs
+++ b/Elternbeirat.Web.Tests/PocketBaseFixture.cs
@@ -317,12 +317,12 @@ public sealed class PocketBaseFixture : IAsyncLifetime
await CreateRecordAsync(http, "faqs", new
{
question = "Wann gibt es Mittagessen?", answer = "Um 12 Uhr.",
- topic = "mensa", @public = true,
+ topic = "Mensa und Mittagessen", @public = true,
});
await CreateRecordAsync(http, "faqs", new
{
question = "Wie viel kostet ein Schließfach?", answer = "20 Euro.",
- topic = "schliessfach", @public = true,
+ topic = "Schließfächer", @public = true,
});
}
diff --git a/Elternbeirat.Web/Features/Faqs/FaqList.razor b/Elternbeirat.Web/Features/Faqs/FaqList.razor
index fdb5102..c1d9d53 100644
--- a/Elternbeirat.Web/Features/Faqs/FaqList.razor
+++ b/Elternbeirat.Web/Features/Faqs/FaqList.razor
@@ -17,7 +17,7 @@ else
@foreach (var group in _groups)
{
- @TopicLabel(group.Key)
+ @group.Key
@foreach (var faq in group)
{
diff --git a/Elternbeirat.Web/Features/Faqs/FaqList.razor.cs b/Elternbeirat.Web/Features/Faqs/FaqList.razor.cs
index fd93102..f2e1802 100644
--- a/Elternbeirat.Web/Features/Faqs/FaqList.razor.cs
+++ b/Elternbeirat.Web/Features/Faqs/FaqList.razor.cs
@@ -14,17 +14,6 @@ public partial class FaqList
ILogger logger,
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 TopicLabels =
- new(StringComparer.Ordinal)
- {
- ["mensa"] = "Mensa und Mittagessen",
- ["schliessfach"] = "Schließfächer",
- ["elterneuro"] = "Eltern-Euro",
- ["elternarbeit"] = "Elternarbeit und Mitmachen",
- };
-
[Inject]
private PocketBaseClient PocketBase { get; set; } = null!;
@@ -57,7 +46,4 @@ public partial class FaqList
SourceUnavailable.SetStatus(HttpContext);
}
}
-
- private static string TopicLabel(string topic)
- => TopicLabels.GetValueOrDefault(topic, topic);
}
diff --git a/docs/redaktion.md b/docs/redaktion.md
index 4dc88be..2cda244 100644
--- a/docs/redaktion.md
+++ b/docs/redaktion.md
@@ -164,10 +164,15 @@ ihrer Kalender-App abonnieren — der Feed entsteht aus denselben Records.
## Häufige Fragen (`faqs`)
-Eine Frage hat `question`, `answer` (Markdown), `topic` (eines von
-`mensa`/`schliessfach`/`elterneuro`/`elternarbeit`) und `public`. Die App baut
-die FAQ-Seite generiert: sie gruppiert die Fragen nach `topic`. Der Rahmentext
-oben auf `/faqs` ist eine eigene Seite in `pages` (Slug `faqs`).
+Eine Frage hat `question`, `answer` (Markdown), `topic` und `public`. Die App
+baut die FAQ-Seite generiert: sie gruppiert die Fragen nach `topic` und zeigt den
+`topic`-Text unverändert als Gruppen-Überschrift. `topic` ist also **keine feste
+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`).
---
diff --git a/pb/pb_migrations/1727200000_dev_seed.js b/pb/pb_migrations/1727200000_dev_seed.js
index d70ec5c..3477406 100644
--- a/pb/pb_migrations/1727200000_dev_seed.js
+++ b/pb/pb_migrations/1727200000_dev_seed.js
@@ -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"}]
,
- 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"}]
,
}
diff --git a/pb/pb_migrations/collections_schema.json b/pb/pb_migrations/collections_schema.json
index 302f8da..db11602 100644
--- a/pb/pb_migrations/collections_schema.json
+++ b/pb/pb_migrations/collections_schema.json
@@ -393,21 +393,19 @@
"type": "text"
},
{
+ "autogeneratePattern": "",
"help": "",
"hidden": false,
"id": "select2638274075",
- "maxSelect": 1,
+ "max": 0,
+ "min": 0,
"name": "topic",
+ "pattern": "",
"presentable": false,
+ "primaryKey": false,
"required": true,
"system": false,
- "type": "select",
- "values": [
- "mensa",
- "schliessfach",
- "elterneuro",
- "elternarbeit"
- ]
+ "type": "text"
},
{
"help": "",