From 6cc007ba55e8d9eddd0679b93645bb8b9511d686 Mon Sep 17 00:00:00 2001 From: Gulum Date: Sat, 6 Jun 2026 00:58:28 +0200 Subject: [PATCH] GEN-2: surface Farbschlag images (FarbschlagImage component) in breeding results, animal detail, form picker Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/components/BreedingResultView.tsx | 2 ++ .../src/components/FarbschlagImage.css | 20 ++++++++++++++ .../src/components/FarbschlagImage.tsx | 25 ++++++++++++++++++ .../src/pages/GerbilDetailPage.tsx | 15 ++++++++++- .../src/pages/GerbilFormPage.tsx | 26 +++++++++++++------ 5 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 gerbil-manager-web/src/components/FarbschlagImage.css create mode 100644 gerbil-manager-web/src/components/FarbschlagImage.tsx diff --git a/gerbil-manager-web/src/components/BreedingResultView.tsx b/gerbil-manager-web/src/components/BreedingResultView.tsx index d054751..b8941ac 100644 --- a/gerbil-manager-web/src/components/BreedingResultView.tsx +++ b/gerbil-manager-web/src/components/BreedingResultView.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' import { de } from '../strings/de' import type { BreedingResult } from '../genetics' +import FarbschlagImage from './FarbschlagImage' function warningText(code: string): string { const map = de.genetics.warnings as Record @@ -44,6 +45,7 @@ export default function BreedingResultView({ result, title }: BreedingResultView
    {result.byFarbschlag.map((f) => (
  • + {f.farbschlag} {f.probability.percent} diff --git a/gerbil-manager-web/src/components/FarbschlagImage.css b/gerbil-manager-web/src/components/FarbschlagImage.css new file mode 100644 index 0000000..9e7f175 --- /dev/null +++ b/gerbil-manager-web/src/components/FarbschlagImage.css @@ -0,0 +1,20 @@ +.farbschlag-thumb { + object-fit: cover; + border-radius: 0.4rem; + border: 1px solid var(--color-border); + background: var(--color-surface); + vertical-align: middle; +} + +/* With a leading thumbnail, let the name grow so the probability stays right. */ +.farbschlag-card .farbschlag-card__name { + flex: 1; +} + +/* Inline image + name (e.g. on the animal detail Stammdaten row). */ +.farbschlag-value { + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + diff --git a/gerbil-manager-web/src/components/FarbschlagImage.tsx b/gerbil-manager-web/src/components/FarbschlagImage.tsx new file mode 100644 index 0000000..a3208ff --- /dev/null +++ b/gerbil-manager-web/src/components/FarbschlagImage.tsx @@ -0,0 +1,25 @@ +import { farbschlagImageUrl, findVariety } from '../genetics' +import './FarbschlagImage.css' + +export interface FarbschlagImageProps { + /** Variety name; may include " Schecke"/" Rex" modifiers (stripped for lookup). */ + name: string + size?: number +} + +/** Thumbnail for a Farbschlag, or null if the variety has no catalog image. */ +export default function FarbschlagImage({ name, size = 40 }: FarbschlagImageProps) { + const baseName = name.replace(/\s+(Schecke|Rex)\b/g, '').trim() + const url = farbschlagImageUrl(findVariety(baseName)?.image ?? findVariety(name)?.image) + if (!url) return null + return ( + {name} + ) +} diff --git a/gerbil-manager-web/src/pages/GerbilDetailPage.tsx b/gerbil-manager-web/src/pages/GerbilDetailPage.tsx index 755bbed..68d89d7 100644 --- a/gerbil-manager-web/src/pages/GerbilDetailPage.tsx +++ b/gerbil-manager-web/src/pages/GerbilDetailPage.tsx @@ -6,6 +6,7 @@ import { listColorVarieties, listContacts, listEnclosures, listLitters } from '. import { useApi } from '../hooks/useApi' import { formatDate, genderLabel, statusLabel } from '../format/labels' import { fromDisplayString, genotypeToFarbschlag, toDisplayString } from '../genetics' +import FarbschlagImage from '../components/FarbschlagImage' // FEAT-6 (Oscar): Tab-Inhalte + Profilfoto import GerbilHealthTab from '../components/GerbilHealthTab' import GerbilPhotosTab from '../components/GerbilPhotosTab' @@ -118,7 +119,19 @@ export default function GerbilDetailPage() { {g.status === 'GivenAway' && ( )} - + + + {storedColorName} + + ) : ( + '—' + ) + } + /> diff --git a/gerbil-manager-web/src/pages/GerbilFormPage.tsx b/gerbil-manager-web/src/pages/GerbilFormPage.tsx index 5600f67..d6750f0 100644 --- a/gerbil-manager-web/src/pages/GerbilFormPage.tsx +++ b/gerbil-manager-web/src/pages/GerbilFormPage.tsx @@ -7,6 +7,7 @@ import { GENDERS, GERBIL_STATUSES, type CreateGerbil, type Gender, type GerbilSt import { useApi, useMutation } from '../hooks/useApi' import { genderLabel, statusLabel } from '../format/labels' import { fromDisplayString } from '../genetics' +import FarbschlagImage from '../components/FarbschlagImage' interface FormState { name: string @@ -173,6 +174,9 @@ export default function GerbilFormPage() { if (isEdit && existing.loading) return

    {de.common.loading}

    + const selectedColorName = + (colorVarieties.data ?? []).find((cv) => cv.id === form.colorVarietyId)?.name ?? null + return (

    {isEdit ? t.form.editTitle : t.form.createTitle}

    @@ -265,14 +269,20 @@ export default function GerbilFormPage() {