feat(windkarte): alle UI-Strings auf t(T.windkarte_*) umgestellt
Deploy / verify (push) Successful in 51s
Deploy / deploy (push) Successful in 59s

Keine hardcodierten Texte mehr — alle Strings über CMS translation_bundle
(app.json5). Keys in translations.ts registriert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-05-13 11:09:09 +02:00
parent 91a09fd3c4
commit ee56a457d3
3 changed files with 47 additions and 25 deletions
+18 -19
View File
@@ -2,6 +2,7 @@
import Icon from "@iconify/svelte";
import "$lib/iconify-offline";
import type { WindArea } from "$lib/windkarte";
import { useTranslate, T } from "$lib/translations";
let {
area,
@@ -13,10 +14,12 @@
onclose: () => void;
} = $props();
const STATUS_LABEL: Record<string, string> = {
rechtskraeftig: "Rechtskräftig",
entwurf_2: "2. Entwurf 2026",
entwurf_3: "3. Entwurf",
const t = useTranslate();
const STATUS_KEY: Record<string, string> = {
rechtskraeftig: T.windkarte_status_rechtskraeftig,
entwurf_2: T.windkarte_status_entwurf_2,
entwurf_3: T.windkarte_status_entwurf_3,
};
const STATUS_CLASS: Record<string, string> = {
rechtskraeftig: "bg-wald-100 text-wald-800",
@@ -38,10 +41,6 @@
setTimeout(() => (copied = false), 2000);
}
$derived: osmHref: center
? `https://www.openstreetmap.org/?mlat=${center[0].toFixed(5)}&mlon=${center[1].toFixed(5)}#map=14/${center[0].toFixed(5)}/${center[1].toFixed(5)}`
: null;
function osmHref(c: [number, number] | null): string | null {
if (!c) return null;
return `https://www.openstreetmap.org/?mlat=${c[0].toFixed(5)}&mlon=${c[1].toFixed(5)}#map=14/${c[0].toFixed(5)}/${c[1].toFixed(5)}`;
@@ -57,7 +56,7 @@
<span class="text-xl font-semibold text-stein-800">{area.gebiets_nr}</span>
{#if area.status}
<span class="rounded-full px-2 py-0.5 text-xs font-medium {STATUS_CLASS[area.status] ?? 'bg-stein-100 text-stein-600'}">
{STATUS_LABEL[area.status] ?? area.status}
{t(STATUS_KEY[area.status] ?? area.status)}
</span>
{/if}
</div>
@@ -68,7 +67,7 @@
<button
onclick={onclose}
class="shrink-0 rounded-md p-1.5 text-stein-400 hover:bg-stein-100 hover:text-stein-700 transition-colors"
aria-label="Panel schließen"
aria-label={t(T.windkarte_panel_close)}
>
<Icon icon="mdi:close" class="size-5" />
</button>
@@ -80,25 +79,25 @@
<div class="grid grid-cols-2 gap-3">
{#if area.flaeche_ha != null}
<div class="rounded-lg bg-stein-50 p-3">
<p class="text-xs text-stein-500">Fläche</p>
<p class="text-xs text-stein-500">{t(T.windkarte_label_flaeche)}</p>
<p class="mt-0.5 font-semibold text-stein-800">{area.flaeche_ha.toFixed(1)} ha</p>
</div>
{/if}
{#if area.anlagen_geplant != null}
<div class="rounded-lg bg-stein-50 p-3">
<p class="text-xs text-stein-500">Geplante Anlagen</p>
<p class="text-xs text-stein-500">{t(T.windkarte_label_anlagen_geplant)}</p>
<p class="mt-0.5 font-semibold text-stein-800">{area.anlagen_geplant}</p>
</div>
{/if}
{#if area.hoehe_max_m != null}
<div class="rounded-lg bg-stein-50 p-3">
<p class="text-xs text-stein-500">Max. Nabenhöhe</p>
<p class="text-xs text-stein-500">{t(T.windkarte_label_hoehe_max)}</p>
<p class="mt-0.5 font-semibold text-stein-800">{area.hoehe_max_m} m</p>
</div>
{/if}
{#if area.investor}
<div class="rounded-lg bg-stein-50 p-3 col-span-2">
<p class="text-xs text-stein-500">Investor / Betreiber</p>
<p class="text-xs text-stein-500">{t(T.windkarte_label_investor)}</p>
<p class="mt-0.5 font-semibold text-stein-800">{area.investor}</p>
</div>
{/if}
@@ -107,7 +106,7 @@
<!-- Gemeinden -->
{#if area.gemeinden && area.gemeinden.length > 0}
<div>
<p class="mb-2 text-xs font-medium uppercase tracking-wide text-stein-500">Betroffene Gemeinden</p>
<p class="mb-2 text-xs font-medium uppercase tracking-wide text-stein-500">{t(T.windkarte_label_gemeinden)}</p>
<div class="flex flex-wrap gap-1.5">
{#each area.gemeinden as g}
<span class="rounded-full bg-himmel-100 px-2.5 py-0.5 text-xs font-medium text-himmel-800">{g}</span>
@@ -119,7 +118,7 @@
<!-- Notizen -->
{#if area.notizen}
<div>
<p class="mb-1.5 text-xs font-medium uppercase tracking-wide text-stein-500">Hinweise</p>
<p class="mb-1.5 text-xs font-medium uppercase tracking-wide text-stein-500">{t(T.windkarte_label_notizen)}</p>
<p class="text-stein-700 leading-relaxed">{area.notizen}</p>
</div>
{/if}
@@ -131,7 +130,7 @@
class="flex items-center gap-2 rounded-lg border border-wald-300 bg-wald-50 px-4 py-3 text-sm font-medium text-wald-700 hover:bg-wald-100 transition-colors"
>
<Icon icon="mdi:file-document-edit-outline" class="size-4 shrink-0" />
Zur Stellungnahme-Vorlage
{t(T.windkarte_stellungnahme_link)}
</a>
{/if}
@@ -142,7 +141,7 @@
class="flex flex-1 items-center justify-center gap-1.5 rounded-lg border border-stein-200 px-2 py-2 text-xs font-medium text-stein-600 hover:bg-stein-50 transition-colors whitespace-nowrap"
>
<Icon icon={copied ? "mdi:check" : "mdi:link-variant"} class="size-3.5 shrink-0" />
{copied ? "Kopiert!" : "Link kopieren"}
{copied ? t(T.windkarte_action_copied) : t(T.windkarte_action_copy_link)}
</button>
{#if osmHref(center)}
<a
@@ -152,7 +151,7 @@
class="flex flex-1 items-center justify-center gap-1.5 rounded-lg border border-stein-200 px-2 py-2 text-xs font-medium text-stein-600 hover:bg-stein-50 transition-colors whitespace-nowrap"
>
<Icon icon="mdi:map-outline" class="size-3.5 shrink-0" />
In OSM öffnen
{t(T.windkarte_action_osm)}
</a>
{/if}
</div>
@@ -5,6 +5,9 @@
import type { WindMapBlockData } from "$lib/block-types";
import type { WindArea } from "$lib/windkarte";
import WindAreaPanel from "$lib/components/WindAreaPanel.svelte";
import { useTranslate, T } from "$lib/translations";
const t = useTranslate();
let { block }: { block: WindMapBlockData } = $props();
@@ -89,8 +92,8 @@
<button
onclick={() => { resetMap?.(); handleSelect(null); }}
class="pointer-events-auto absolute top-2.5 right-2.5 z-[500] rounded-md bg-white/90 p-1.5 shadow-md text-stein-500 hover:text-stein-800 hover:bg-white transition-colors"
aria-label="Übersicht zurücksetzen"
title="Übersicht zurücksetzen"
aria-label={t(T.windkarte_reset_aria)}
title={t(T.windkarte_reset_aria)}
>
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
@@ -111,7 +114,7 @@
{/await}
{:else}
<div class="flex h-full items-center justify-center bg-stein-50 text-stein-400 text-sm">
Karte wird geladen …
{t(T.windkarte_loading)}
</div>
{/if}
@@ -129,14 +132,14 @@
<div class="mt-2 flex flex-wrap gap-x-5 gap-y-1.5 text-xs text-stein-400">
<span class="flex items-center gap-1.5">
<span class="inline-block size-2.5 rounded-sm" style="background:#2d7a45; opacity:.7"></span>
Rechtskräftig (2012)
{t(T.windkarte_legend_rechtskraeftig)}
</span>
<span class="flex items-center gap-1.5">
<span class="inline-block size-2.5 rounded-sm" style="background:#b08a52; opacity:.7"></span>
2. Entwurf 2026
{t(T.windkarte_legend_entwurf_2)}
</span>
<span class="flex items-center gap-x-3 gap-y-1 flex-wrap text-stein-300">
<span class="text-stein-400">Abstände:</span>
<span class="text-stein-400">{t(T.windkarte_legend_distances)}</span>
{#each [{ color: "#e35651", label: "200 m" }, { color: "#b08a52", label: "600 m" }, { color: "#436e85", label: "1 km" }] as ring}
<span class="flex items-center gap-1.5">
<span class="dashed-line" style="border-color:{ring.color}"></span>
+20
View File
@@ -196,6 +196,26 @@ const TRANSLATION_KEYS = [
"post_action_copied",
"post_action_print",
"post_action_reading_time",
// Windkarte (WindkarteBlock / WindAreaPanel).
"windkarte_loading",
"windkarte_panel_close",
"windkarte_reset_aria",
"windkarte_status_rechtskraeftig",
"windkarte_status_entwurf_2",
"windkarte_status_entwurf_3",
"windkarte_label_flaeche",
"windkarte_label_anlagen_geplant",
"windkarte_label_hoehe_max",
"windkarte_label_investor",
"windkarte_label_gemeinden",
"windkarte_label_notizen",
"windkarte_stellungnahme_link",
"windkarte_action_copy_link",
"windkarte_action_copied",
"windkarte_action_osm",
"windkarte_legend_rechtskraeftig",
"windkarte_legend_entwurf_2",
"windkarte_legend_distances",
// Strommix-Live-Widget (StrommixBlock.svelte).
"strommix_header",
"strommix_stand", // {{time}}