feat(stellungnahme): Einwendungs-Assistent für Windvorranggebiete
5-Schritt-Wizard: Gebietskontext → Argumente wählen → Ausgabeform → persönliche Betroffenheit → Absender + Ausgabe. Alle Eingaben bleiben lokal im Browser (kein Server-Transfer). Fertigtext- und Leitfaden-Modus. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,8 @@ import {
|
||||
getPostBySlug,
|
||||
getTags,
|
||||
getTextFragmentBySlug,
|
||||
getTextFragmentsByTag,
|
||||
getEntryBySlug,
|
||||
getCalendarBySlug,
|
||||
getCalendarItemBySlug,
|
||||
getCalendarItems,
|
||||
@@ -760,3 +762,74 @@ export async function resolveSearchableTextBlocks(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isStellingnahmeGeneratorBlock(item: unknown): boolean {
|
||||
return (item as { _type?: string })?._type === "stellungnahme_generator";
|
||||
}
|
||||
|
||||
/** Löst stellungnahme_generator-Blöcke auf:
|
||||
* - windArea → vollständiges wind_area-Objekt mit aufgelösten stellungnahme_kriterien
|
||||
* - allgemeineArgumenteTag → allgemeineArgumente[] via Tag-Filter
|
||||
*/
|
||||
export async function resolveStellingnahmeGeneratorBlocks(
|
||||
layout: RowContentLayout | null | undefined,
|
||||
): Promise<void> {
|
||||
if (!layout) return;
|
||||
const rows = [
|
||||
layout.row1Content ?? [],
|
||||
layout.row2Content ?? [],
|
||||
layout.row3Content ?? [],
|
||||
];
|
||||
for (const content of rows) {
|
||||
if (!Array.isArray(content)) continue;
|
||||
for (const item of content) {
|
||||
if (!isStellingnahmeGeneratorBlock(item)) continue;
|
||||
const block = item as Record<string, unknown>;
|
||||
|
||||
// Resolve windArea
|
||||
const windAreaRef = block.windArea;
|
||||
const windAreaSlug =
|
||||
typeof windAreaRef === "string"
|
||||
? windAreaRef
|
||||
: (windAreaRef as { _slug?: string })?._slug ?? "";
|
||||
if (windAreaSlug) {
|
||||
const windArea = await getEntryBySlug("wind_area", windAreaSlug, {
|
||||
locale: "de",
|
||||
resolve: ["stellungnahme_kriterien"],
|
||||
depth: 2,
|
||||
});
|
||||
if (windArea) {
|
||||
const kriterienRaw =
|
||||
(windArea as { stellungnahme_kriterien?: unknown[] })
|
||||
.stellungnahme_kriterien ?? [];
|
||||
// Fragmente einzeln laden um bulletPoints zu bekommen (nicht im Basis-Resolve)
|
||||
const kriterien = await Promise.all(
|
||||
kriterienRaw.map(async (k) => {
|
||||
const slug =
|
||||
typeof k === "string"
|
||||
? k
|
||||
: (k as { _slug?: string })?._slug ?? "";
|
||||
if (!slug) return null;
|
||||
return getTextFragmentBySlug(slug, { locale: "de" });
|
||||
}),
|
||||
);
|
||||
(windArea as Record<string, unknown>).stellungnahme_kriterien =
|
||||
kriterien.filter(Boolean);
|
||||
block.windArea = windArea;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve allgemeineArgumente via Tag
|
||||
const tagRef = block.allgemeineArgumenteTag;
|
||||
const tagSlug =
|
||||
typeof tagRef === "string"
|
||||
? tagRef
|
||||
: (tagRef as { _slug?: string })?._slug ?? "";
|
||||
if (tagSlug) {
|
||||
block.allgemeineArgumente = await getTextFragmentsByTag(tagSlug, {
|
||||
locale: "de",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user