- de.ts: alle nutzer-sichtbaren 'Becken'-Strings → 'Gehege' (nav, fields, titles, buttons, validation, delete, hilfe sections) - AppShell.tsx: route /becken → /gehege, icon 🛁 → 🏜️ (Wüsten-Habitat) - App.tsx: <Route path="gehege"> + <Route path="becken/*"> redirect (bewahrt Bookmarks; BeckenRedirect leitet Unterseiten 1:1 weiter) - BeckenPage/DetailPage/FormPage: interne Links /becken → /gehege - HilfePage.tsx: hartcodierte 'Becken'-Prosa → 'Gehege' - e2e/becken-kontakte.spec.ts: goto('/becken') → goto('/gehege') Gate: build ✓ eslint ✓ vitest 82/82 ✓ e2e 120/120 ✓
235 lines
13 KiB
TypeScript
235 lines
13 KiB
TypeScript
/**
|
||
* HELP-1: In-App-Anleitung für die Züchterin (nicht-technisch, du-Form).
|
||
* Accordion via <details>/<summary> — kein JS-State nötig, barrierefrei, mobiltauglich.
|
||
* Texte referenzieren nur Bezeichnungen aus de.ts (bleiben bei Umbenennung korrekt).
|
||
*/
|
||
import { de } from '../strings/de'
|
||
import './hilfe.css'
|
||
|
||
const t = de.hilfe
|
||
const nav = de.nav
|
||
const g = de.pages.gerbils
|
||
const l = de.pages.litters
|
||
const b = de.pages.becken
|
||
const st = de.pages.stammbaum
|
||
const ge = de.pages.genetik
|
||
const ab = de.pages.abgabe
|
||
const stat = de.pages.statistik
|
||
// FEAT-13-Followup: Vertrag + Zuchtprofil
|
||
const v = de.pages.vertraege
|
||
const vw = de.pages.vertraege.wizard
|
||
const ez = de.pages.einstellungen.zuchtprofil
|
||
const scheckeWarning = de.genetics.warnings.SCHECKE_LETHAL
|
||
const rexWarning = de.genetics.warnings.REX_SEMI_LETHAL
|
||
|
||
interface Section {
|
||
id: string
|
||
title: string
|
||
content: React.ReactNode
|
||
}
|
||
|
||
const sections: Section[] = [
|
||
{
|
||
id: 'erste-schritte',
|
||
title: t.sections.ersteSchritte,
|
||
content: (
|
||
<>
|
||
<p>Willkommen im <strong>{de.app.title}</strong>! Diese Anleitung führt dich durch die wichtigsten Bereiche.</p>
|
||
<p>Die Navigation erreichst du unten (Smartphone) oder links (Laptop). Mit <strong>„{nav.more}"</strong> öffnest du alle weiteren Bereiche.</p>
|
||
<p>Empfohlene Reihenfolge beim ersten Mal:</p>
|
||
<ol>
|
||
<li>Gehege anlegen (wo leben deine Tiere?)</li>
|
||
<li>Rennmäuse anlegen mit Foto</li>
|
||
<li>Würfe eintragen</li>
|
||
<li>Genetik erkunden</li>
|
||
</ol>
|
||
<p className="hilfe-hint">Tipp: Lege zuerst die Gehege an — dann kannst du beim Erfassen der Tiere direkt das richtige Gehege auswählen.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'tiere',
|
||
title: t.sections.tiere,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.gerbils}"</strong> siehst du alle deine Rennmäuse. Mit <strong>„{g.newButton}"</strong> legst du ein neues Tier an.</p>
|
||
<p>Pflichtfelder sind <strong>„{g.fields.name}"</strong> und <strong>„{g.fields.gender}"</strong>. Optional kannst du Geburtsdatum, Farbschlag, Genotyp, Gehege und Herkunft eintragen.</p>
|
||
<p>Auf der Detailseite findest du drei Tabs:</p>
|
||
<ul>
|
||
<li><strong>„{g.detail.tabs.photos}"</strong> — Fotos hochladen; das erste Foto wird als Profilfoto angezeigt.</li>
|
||
<li><strong>„{g.detail.tabs.health}"</strong> — Tierarztbesuche, Behandlungen und Untersuchungen eintragen.</li>
|
||
<li><strong>„{g.detail.tabs.weight}"</strong> — Gewicht in Gramm erfassen; nach zwei Einträgen erscheint eine Verlaufskurve.</li>
|
||
</ul>
|
||
<p>Mit den Filtern oben in der Liste kannst du nach Status, Geschlecht und Farbschlag filtern oder nach Name suchen.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'becken',
|
||
title: t.sections.becken,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.enclosures}"</strong> verwaltest du deine Gehege. Mit <strong>„{b.newButton}"</strong> legst du ein neues Gehege an (nur Name ist Pflicht).</p>
|
||
<p>Die Detailseite zeigt dir die aktuellen <strong>„{b.occupancy.title}"</strong> — mit Links direkt zur Tierakte. So siehst du auf einen Blick, wer wo lebt.</p>
|
||
<p>Ein Gehege lässt sich nur löschen, wenn es leer ist — das schützt vor versehentlichem Datenverlust.</p>
|
||
<p>Unter <strong>„{nav.contacts}"</strong> kannst du Züchter, Käufer und andere Kontakte anlegen. Diese lassen sich dann als Herkunft oder Abnehmer bei Tieren eintragen.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'wuerfe',
|
||
title: t.sections.wuerfe,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.litters}"</strong> erfasst du Würfe. Mit <strong>„{l.newButton}"</strong> trägst du Vater, Mutter, Wurfdatum und Wurfstärke ein.</p>
|
||
<p>Das <strong>„{l.fields.expectedGoHomeDate}"</strong> wird automatisch auf 35 Tage nach dem Wurfdatum vorgeschlagen — du kannst es anpassen.</p>
|
||
<p>Auf der Wurf-Detailseite siehst du unter <strong>„{l.detail.registered}"</strong> die bereits erfassten Jungtiere. Mit <strong>„{l.detail.registerJuvenile}"</strong> legst du ein neues Tier an, das direkt mit diesem Wurf verknüpft ist.</p>
|
||
<p>Im Tab <strong>„{l.tabs.pairs}"</strong> siehst du alle Verpaarungen aus deinen Würfen auf einen Blick — mit Anzahl Würfe und Datum des letzten Wurfes.</p>
|
||
<p className="hilfe-hint">Tipp: Wenn du auf der Genetik-Seite eine Probeverpaarung berechnest, kannst du mit <strong>„Probeverpaarung"</strong> direkt zur Genetikseite springen und das Tierpaar vorauswählen.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'genetik',
|
||
title: t.sections.genetik,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.genetics}"</strong> berechnest du, welche Farbschläge bei einer Verpaarung möglich sind.</p>
|
||
<p>Wähle <strong>„{ge.father}"</strong> und <strong>„{ge.mother}"</strong> aus deinen Tieren oder gib die Genotypen manuell ein. Klicke dann auf <strong>„{ge.run}"</strong>.</p>
|
||
<p>Das Ergebnis zeigt alle möglichen Farbschläge mit Wahrscheinlichkeit — du kannst zwischen Anzeige nach Farbschlag und nach Genotyp wechseln.</p>
|
||
<p><strong>Wichtige Warnungen:</strong></p>
|
||
<ul>
|
||
<li className="hilfe-warning"><strong>Schecke × Schecke:</strong> {scheckeWarning}</li>
|
||
<li className="hilfe-warning"><strong>Rex × Rex:</strong> {rexWarning}</li>
|
||
</ul>
|
||
<p>Diese Warnungen erscheinen automatisch, wenn die entsprechende Kombination erkannt wird. Bitte beachte sie beim Zuchtentscheid.</p>
|
||
<p>Den Genotyp eines Tieres trägst du auf der Tier-Detailseite unter <strong>„{g.detail.masterData}"</strong> ein. Format: z. B. <code>Aa CC Dd EE GG Pp Spsp rere</code>. Unbekannte Stellen als <code>?</code>.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'stammbaum',
|
||
title: t.sections.stammbaum,
|
||
content: (
|
||
<>
|
||
<p>Auf der Tier-Detailseite öffnest du mit <strong>„{st.openButton}"</strong> den interaktiven Stammbaum.</p>
|
||
<p><strong>Navigieren:</strong> {st.tapHint}</p>
|
||
<p><strong>Zoomen:</strong> Mit den Schaltflächen <strong>„{st.zoomIn}"</strong> / <strong>„{st.zoomOut}"</strong> oder per Pinch-Geste auf dem Smartphone. <strong>„{st.zoomFit}"</strong> passt die Ansicht an den Bildschirm an.</p>
|
||
<p><strong>Drucken / PDF:</strong> Mit <strong>„{st.print}"</strong> öffnest du die Druckansicht (Ahnentafel). Wähle im Druckdialog „Als PDF speichern", um eine Datei zu erzeugen.</p>
|
||
<p>Der <strong>„{st.inbreeding.label}"</strong> wird automatisch für das angezeigte Tier berechnet und oben angezeigt.</p>
|
||
<p className="hilfe-hint">Tipp: Je mehr Elterntiere und Würfe du erfasst hast, desto tiefer reicht der Stammbaum.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'abgabe',
|
||
title: t.sections.abgabe,
|
||
content: (
|
||
<>
|
||
<p>Der Abgabe-Ablauf läuft in mehreren Schritten:</p>
|
||
<ol>
|
||
<li>
|
||
<strong>Tier zur Abgabe stellen:</strong> Öffne die Tierakte und klicke auf <strong>„{ab.markAction}"</strong>. Das Tier wechselt in den Status <em>„{de.pages.gerbils.statusLabels.ForSale}"</em>.
|
||
</li>
|
||
<li>
|
||
<strong>Gruppen bilden:</strong> Auf der <strong>„{nav.forSale}"</strong>-Seite werden Tiere nach Becken vorgruppiert. Du kannst Tiere zwischen Gruppen verschieben oder neue Gruppen anlegen.
|
||
</li>
|
||
<li>
|
||
<strong>Inserat erstellen:</strong> Fülle für jede Gruppe den emotionalen Einzeiler und den Charakter-Text aus.
|
||
</li>
|
||
<li>
|
||
<strong>Text kopieren & Fotos herunterladen:</strong> Mit <strong>„{ab.export.copyText}"</strong> kommt der fertige Inseratstext in die Zwischenablage. Mit <strong>„{ab.export.downloadPhotos}"</strong> lädst du alle Fotos der Gruppe als ZIP herunter.
|
||
</li>
|
||
<li>
|
||
<strong>KI-Unterstützung (optional):</strong> Mit <strong>„{ab.ai.improve}"</strong> kann der Text automatisch verbessert werden — dazu ist ein API-Schlüssel nötig.
|
||
</li>
|
||
<li>
|
||
<strong>Abschließen:</strong> Sind die Tiere vergeben, klicke in der Gruppe auf <strong>„{ab.export.finish}"</strong> — das öffnet den Vertrags-Assistenten mit den Tieren der Gruppe (siehe Abschnitt <em>„{t.sections.vertraege}"</em>).
|
||
</li>
|
||
</ol>
|
||
<p className="hilfe-hint">Tipp: Bearbeite jede Gruppe einzeln — Text und Fotos für eine Gruppe gleichzeitig zusammenstellen, dann weiter zur nächsten.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'vertraege',
|
||
title: t.sections.vertraege,
|
||
content: (
|
||
<>
|
||
<p>Den Vertrags-Assistenten <strong>„{vw.title}"</strong> erreichst du auf drei Wegen: über <strong>„{ab.export.finish}"</strong> in einer Abgabe-Gruppe, über den gleichnamigen Knopf auf der Tierakte oder unter <strong>„{nav.contracts}"</strong> → <strong>„{v.newButton}"</strong>.</p>
|
||
<p>Der Assistent führt dich in vier Schritten durch die Abgabe:</p>
|
||
<ol>
|
||
<li><strong>„{vw.steps[0]}"</strong> — wähle den Käufer aus deinen Kontakten oder lege ihn direkt an (Name, Adresse, Telefon, E-Mail — so erscheinen sie im Vertrag).</li>
|
||
<li><strong>„{vw.steps[1]}"</strong> — bestätige die Tiere; kommst du aus einer Abgabe-Gruppe oder Tierakte, sind sie schon angehakt.</li>
|
||
<li><strong>„{vw.steps[2]}"</strong> — Kaufpreis (z. B. <code>72,00</code>) und Übergabedatum eintragen.</li>
|
||
<li><strong>„{vw.steps[3]}"</strong> — Zusammenfassung prüfen und <strong>„{vw.generate}"</strong> klicken.</li>
|
||
</ol>
|
||
<p>Danach kannst du den fertigen Vertrag als <strong>Word-Datei (.docx)</strong> herunterladen — er sieht aus wie deine bisherigen Verträge, mit deinen Zuchtdaten, dem Käufer und einer Tabelle pro Tier. Gleichzeitig werden die Tiere automatisch als <em>„{de.pages.gerbils.statusLabels.GivenAway}"</em> markiert (Abnehmer und Abgabedatum sind dann in der Tierakte eingetragen).</p>
|
||
<p>Alle erstellten Verträge findest du unter <strong>„{nav.contracts}"</strong> — dort kannst du sie jederzeit erneut <strong>„{v.download}"</strong> oder löschen.</p>
|
||
<p className="hilfe-hint">Tipp: Fülle zuerst dein Zuchtprofil aus (siehe Abschnitt „{t.sections.einstellungen}") — diese Angaben erscheinen als Verkäufer-Block in jedem Vertrag.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'einstellungen',
|
||
title: t.sections.einstellungen,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.settings}"</strong> pflegst du dein <strong>„{ez.title}"</strong>: {ez.intro}</p>
|
||
<p>Wichtig für den Vertrag sind <strong>„{ez.fields.name}"</strong>, <strong>„{ez.fields.address}"</strong> und <strong>„{ez.fields.city}"</strong> (der Ort erscheint in der Unterschriftszeile). Zuchtname, Telefon, E-Mail und Homepage vervollständigen den Briefkopf.</p>
|
||
<p>Solange etwas fehlt, zeigen die Einstellungen und der Vertrags-Assistent einen Hinweis — du musst die Angaben nur einmal eintragen.</p>
|
||
<p>Außerdem findest du hier den <strong>„{de.pages.datenexport.title}"</strong>, mit dem du alle Daten als Zip herunterladen kannst.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'statistik',
|
||
title: t.sections.statistik,
|
||
content: (
|
||
<>
|
||
<p>Unter <strong>„{nav.statistics}"</strong> findest du Auswertungen über deinen Bestand:</p>
|
||
<ul>
|
||
<li><strong>„{stat.littersPerYear}"</strong> — wie viele Würfe pro Jahr.</li>
|
||
<li><strong>„{stat.avgLitterSize}"</strong> — durchschnittliche Wurfstärke pro Jahr.</li>
|
||
<li><strong>„{stat.farbschlag}"</strong> — wie viele aktive Tiere welchen Farbschlag haben.</li>
|
||
<li><strong>„{stat.population}"</strong> — wie sich dein Bestand über die Zeit entwickelt hat.</li>
|
||
<li><strong>„{stat.losses}"</strong> — verstorbene Tiere nach Jahr.</li>
|
||
</ul>
|
||
<p>Die Statistiken werden automatisch aus deinen Daten berechnet. Je vollständiger deine Einträge (Geburtsdaten, Farbschläge, Wurfstärken), desto aussagekräftiger die Auswertungen.</p>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
id: 'datensicherung',
|
||
title: t.sections.datensicherung,
|
||
content: (
|
||
<>
|
||
<p>Deine Daten liegen sicher auf Julian's Server zu Hause — kein Cloud-Konto nötig.</p>
|
||
<p>Julian erstellt automatisch jeden Nacht um 3 Uhr ein Backup der Datenbank und aller Fotos. Bei einem Problem kann er den Stand eines beliebigen Tages wiederherstellen.</p>
|
||
<p className="hilfe-hint">Wenn du versehentlich Daten gelöscht hast, wende dich an Julian. Er kann aus einem der letzten 7 Tages-Backups wiederherstellen.</p>
|
||
</>
|
||
),
|
||
},
|
||
]
|
||
|
||
export default function HilfePage() {
|
||
return (
|
||
<section className="page hilfe-page">
|
||
<h2>{t.title}</h2>
|
||
<p className="hilfe-subtitle">{t.subtitle}</p>
|
||
|
||
<div className="hilfe-accordion">
|
||
{sections.map((s) => (
|
||
<details key={s.id} className="hilfe-section">
|
||
<summary className="hilfe-section-summary">
|
||
<span className="hilfe-section-title">{s.title}</span>
|
||
<span className="hilfe-section-chevron" aria-hidden="true">▾</span>
|
||
</summary>
|
||
<div className="hilfe-section-body">{s.content}</div>
|
||
</details>
|
||
))}
|
||
</div>
|
||
</section>
|
||
)
|
||
}
|