diff --git a/gerbil-manager-web/e2e/becken-kontakte.spec.ts b/gerbil-manager-web/e2e/becken-kontakte.spec.ts index 7a8feb8..90a7e1f 100644 --- a/gerbil-manager-web/e2e/becken-kontakte.spec.ts +++ b/gerbil-manager-web/e2e/becken-kontakte.spec.ts @@ -7,7 +7,7 @@ const tk = de.pages.kontakte test.describe('Becken', () => { test('Belegung: Detail zeigt Bewohner mit Link zur Tierakte', async ({ page }) => { skipUnlessMock() - await page.goto('/becken') + await page.goto('/gehege') await page.getByRole('link', { name: /Großbecken/ }).click() await expect(page.getByRole('heading', { name: 'Großbecken' })).toBeVisible() await expect(page.getByText(`2 ${tb.occupancy.countMany}`)).toBeVisible() @@ -18,7 +18,7 @@ test.describe('Becken', () => { test('Löschen eines belegten Beckens meldet den 409-Konflikt auf Deutsch', async ({ page }) => { skipUnlessMock() - await page.goto('/becken') + await page.goto('/gehege') await page.getByRole('link', { name: /Großbecken/ }).click() acceptNextDialog(page) await page.getByRole('button', { name: tb.delete.action }).click() diff --git a/gerbil-manager-web/src/App.tsx b/gerbil-manager-web/src/App.tsx index 017dfb2..3d17786 100644 --- a/gerbil-manager-web/src/App.tsx +++ b/gerbil-manager-web/src/App.tsx @@ -1,4 +1,4 @@ -import { BrowserRouter, Route, Routes } from 'react-router-dom' +import { BrowserRouter, Navigate, Route, Routes, useParams } from 'react-router-dom' import AppShell from './components/AppShell' import BeckenPage from './pages/BeckenPage' import BeckenDetailPage from './pages/BeckenDetailPage' @@ -28,6 +28,11 @@ import WebseiteVorschauPage from './pages/WebseiteVorschauPage' import AnfragenPage from './pages/AnfragenPage' import AnfrageDetailPage from './pages/AnfrageDetailPage' +function BeckenRedirect() { + const { '*': splat } = useParams() + return +} + export default function App() { return ( @@ -48,7 +53,9 @@ export default function App() { } /> {/* FEAT-2: Kontakte ersetzt das Züchter-Platzhalter-Routing (Breeder -> Contact) */} - + {/* GEHEGE-RENAME: /becken → /gehege; redirect preserves bookmarks */} + } /> + } /> } /> } /> diff --git a/gerbil-manager-web/src/components/AppShell.tsx b/gerbil-manager-web/src/components/AppShell.tsx index d3c702c..8e35994 100644 --- a/gerbil-manager-web/src/components/AppShell.tsx +++ b/gerbil-manager-web/src/components/AppShell.tsx @@ -19,7 +19,7 @@ const PRIMARY: NavItem[] = [ { to: '/genetik', label: de.nav.genetics, icon: '🧬' }, ] const SECONDARY: NavItem[] = [ - { to: '/becken', label: de.nav.enclosures, icon: '🛁' }, + { to: '/gehege', label: de.nav.enclosures, icon: '🏜️' }, { to: '/kontakte', label: de.nav.contacts, icon: '📇' }, { to: '/abgabe', label: de.nav.forSale, icon: '🏡' }, // INBOX-1: Anfragen-Posteingang diff --git a/gerbil-manager-web/src/pages/BeckenDetailPage.tsx b/gerbil-manager-web/src/pages/BeckenDetailPage.tsx index 2ba666c..6cafc8f 100644 --- a/gerbil-manager-web/src/pages/BeckenDetailPage.tsx +++ b/gerbil-manager-web/src/pages/BeckenDetailPage.tsx @@ -44,7 +44,7 @@ export default function BeckenDetailPage() { setDeleteError(null) const result = await removal.run() if (result.ok) { - navigate('/becken') + navigate('/gehege') } else if (result.cause instanceof ApiError && result.cause.status === 409) { // Backend meldet Konflikt, wenn noch Tiere im Becken wohnen. setDeleteError(t.delete.conflict) @@ -58,7 +58,7 @@ export default function BeckenDetailPage() { return (

{enclosure.error ?? t.detail.notFound}

- + {t.detail.back}
@@ -81,7 +81,7 @@ export default function BeckenDetailPage() { )}
- + {t.detail.edit} - + {t.detail.back}
diff --git a/gerbil-manager-web/src/pages/BeckenFormPage.tsx b/gerbil-manager-web/src/pages/BeckenFormPage.tsx index f7df10c..5d6bd53 100644 --- a/gerbil-manager-web/src/pages/BeckenFormPage.tsx +++ b/gerbil-manager-web/src/pages/BeckenFormPage.tsx @@ -45,7 +45,7 @@ export default function BeckenFormPage() { } setErrors({}) const result = await mutation.run({ name: form.name.trim(), notes: nn(form.notes) }) - if (result.ok) navigate(`/becken/${result.value.id}`) + if (result.ok) navigate(`/gehege/${result.value.id}`) // On failure mutation.error drives the inline alert; run() never throws. } @@ -81,7 +81,7 @@ export default function BeckenFormPage() { - + {t.form.cancel} diff --git a/gerbil-manager-web/src/pages/BeckenPage.tsx b/gerbil-manager-web/src/pages/BeckenPage.tsx index 7e0dd2f..b47bf7d 100644 --- a/gerbil-manager-web/src/pages/BeckenPage.tsx +++ b/gerbil-manager-web/src/pages/BeckenPage.tsx @@ -35,7 +35,7 @@ export default function BeckenPage() {

)} - + + {t.newButton} @@ -72,7 +72,7 @@ export default function BeckenPage() {
    {items.map((e) => (
  • - + {e.name} {e.notes ?? ''} diff --git a/gerbil-manager-web/src/pages/HilfePage.tsx b/gerbil-manager-web/src/pages/HilfePage.tsx index 4d1d3ef..eabf3ca 100644 --- a/gerbil-manager-web/src/pages/HilfePage.tsx +++ b/gerbil-manager-web/src/pages/HilfePage.tsx @@ -38,12 +38,12 @@ const sections: Section[] = [

    Die Navigation erreichst du unten (Smartphone) oder links (Laptop). Mit „{nav.more}" öffnest du alle weiteren Bereiche.

    Empfohlene Reihenfolge beim ersten Mal:

      -
    1. Becken anlegen (wo leben deine Tiere?)
    2. +
    3. Gehege anlegen (wo leben deine Tiere?)
    4. Rennmäuse anlegen mit Foto
    5. Würfe eintragen
    6. Genetik erkunden
    -

    Tipp: Lege zuerst die Becken an — dann kannst du beim Erfassen der Tiere direkt das richtige Becken auswählen.

    +

    Tipp: Lege zuerst die Gehege an — dann kannst du beim Erfassen der Tiere direkt das richtige Gehege auswählen.

    ), }, @@ -53,7 +53,7 @@ const sections: Section[] = [ content: ( <>

    Unter „{nav.gerbils}" siehst du alle deine Rennmäuse. Mit „{g.newButton}" legst du ein neues Tier an.

    -

    Pflichtfelder sind „{g.fields.name}" und „{g.fields.gender}". Optional kannst du Geburtsdatum, Farbschlag, Genotyp, Becken und Herkunft eintragen.

    +

    Pflichtfelder sind „{g.fields.name}" und „{g.fields.gender}". Optional kannst du Geburtsdatum, Farbschlag, Genotyp, Gehege und Herkunft eintragen.

    Auf der Detailseite findest du drei Tabs:

    • „{g.detail.tabs.photos}" — Fotos hochladen; das erste Foto wird als Profilfoto angezeigt.
    • @@ -69,9 +69,9 @@ const sections: Section[] = [ title: t.sections.becken, content: ( <> -

      Unter „{nav.enclosures}" verwaltest du deine Gehege. Mit „{b.newButton}" legst du ein neues Becken an (nur Name ist Pflicht).

      +

      Unter „{nav.enclosures}" verwaltest du deine Gehege. Mit „{b.newButton}" legst du ein neues Gehege an (nur Name ist Pflicht).

      Die Detailseite zeigt dir die aktuellen „{b.occupancy.title}" — mit Links direkt zur Tierakte. So siehst du auf einen Blick, wer wo lebt.

      -

      Ein Becken lässt sich nur löschen, wenn es leer ist — das schützt vor versehentlichem Datenverlust.

      +

      Ein Gehege lässt sich nur löschen, wenn es leer ist — das schützt vor versehentlichem Datenverlust.

      Unter „{nav.contacts}" kannst du Züchter, Käufer und andere Kontakte anlegen. Diese lassen sich dann als Herkunft oder Abnehmer bei Tieren eintragen.

      ), diff --git a/gerbil-manager-web/src/strings/de.ts b/gerbil-manager-web/src/strings/de.ts index 2fdb0a0..7709b89 100644 --- a/gerbil-manager-web/src/strings/de.ts +++ b/gerbil-manager-web/src/strings/de.ts @@ -14,8 +14,8 @@ export const de = { litters: 'Würfe', breeders: 'Züchter', genetics: 'Genetik', - // FEAT-2 (Oscar): Becken + Kontakte - enclosures: 'Becken', + // FEAT-2 (Oscar): Becken + Kontakte (GEHEGE-RENAME: Becken → Gehege) + enclosures: 'Gehege', contacts: 'Kontakte', // FEAT-7 (Kelly): Statistik statistics: 'Statistik', @@ -82,7 +82,7 @@ export const de = { causeOfDeath: 'Todesursache', goHomeDate: 'Abgabedatum', litter: 'Wurf', - enclosure: 'Becken', + enclosure: 'Gehege', colorVariety: 'Farbschlag', origin: 'Herkunft', receiver: 'Abnehmer', @@ -253,8 +253,8 @@ export const de = { markMultiAction: 'Ausgewählte zur Abgabe stellen', grouping: { title: 'Gruppen', - byEnclosure: 'Nach Becken vorgeschlagen', - ungrouped: 'Ohne Becken', + byEnclosure: 'Nach Gehege vorgeschlagen', + ungrouped: 'Ohne Gehege', moveTo: 'Verschieben nach', newGroup: 'Neue Gruppe', groupLabel: 'Gruppe', @@ -298,12 +298,12 @@ export const de = { notConfigured: 'KI-Funktion: API-Schlüssel noch nicht konfiguriert.', }, }, - // ── FEAT-2 (Oscar): Becken (Enclosures) ── + // ── FEAT-2 (Oscar): Gehege (Enclosures) — GEHEGE-RENAME: Becken → Gehege ── becken: { - title: 'Becken', - newButton: 'Neues Becken', - empty: 'Keine Becken gefunden.', - countLabel: 'Becken', + title: 'Gehege', + newButton: 'Neues Gehege', + empty: 'Keine Gehege gefunden.', + countLabel: 'Gehege', searchPlaceholder: 'Name suchen …', fields: { name: 'Name', @@ -311,18 +311,18 @@ export const de = { }, occupancy: { title: 'Bewohner', - empty: 'Dieses Becken ist derzeit leer.', + empty: 'Dieses Gehege ist derzeit leer.', countOne: 'Tier', countMany: 'Tiere', }, detail: { edit: 'Bearbeiten', back: 'Zurück zur Liste', - notFound: 'Dieses Becken wurde nicht gefunden.', + notFound: 'Dieses Gehege wurde nicht gefunden.', }, form: { - createTitle: 'Neues Becken anlegen', - editTitle: 'Becken bearbeiten', + createTitle: 'Neues Gehege anlegen', + editTitle: 'Gehege bearbeiten', save: 'Speichern', cancel: 'Abbrechen', saving: 'Speichern …', @@ -332,9 +332,9 @@ export const de = { }, delete: { action: 'Löschen', - confirmMessage: 'Soll dieses Becken wirklich gelöscht werden?', + confirmMessage: 'Soll dieses Gehege wirklich gelöscht werden?', conflict: - 'Becken ist nicht leer — bitte zuerst alle Tiere in ein anderes Becken umsetzen.', + 'Gehege ist nicht leer — bitte zuerst alle Tiere in ein anderes Gehege umsetzen.', }, }, // ── FEAT-4 (Kelly): Stammbaum (Ahnentafel) ── @@ -731,7 +731,7 @@ export const de = { sections: { ersteSchritte: 'Erste Schritte', tiere: 'Rennmäuse anlegen & Fotos', - becken: 'Becken', + becken: 'Gehege', wuerfe: 'Würfe & Jungtiere', genetik: 'Probeverpaarung & Genetik', stammbaum: 'Stammbaum',