fix(statistics): feeding totals per unit instead of adding litres to kilograms

The feeding statistics summed every amount regardless of its unit, so
5 l syrup and 2 kg fondant showed as 7. The API now also returns byUnit
(units normalised: "L" = "l"), the old fields stay for compatibility,
and the statistics page shows one list per unit.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-01 12:27:24 +02:00
1 parent ed0a000534
commit 2bc0db6f33
4 files changed
+92 -45

No files matched your search

@@ -293,49 +293,62 @@ function FeedingStatsPanel({ colonyLabels }: { colonyLabels: Map<string, string>
return (
<QueryState query={query} what="Futterdaten">
{(data) => (
<div className="flex flex-col gap-4">
<PanelHint>
Summe der eingetragenen Futtermengen in Liter bzw. kg, so wie sie bei der Fütterung
erfasst wurden.
</PanelHint>
<Card>
<CardHeader>
<CardTitle>Futterverbrauch pro Volk</CardTitle>
</CardHeader>
<CardContent>
<StatBarList
items={Object.entries(data.byColony)
.sort(([, a], [, b]) => b - a)
.slice(0, 10)
.map(([colonyId, value]) => ({
label: colonyLabels.get(colonyId) ?? colonyId,
value,
unit: FEED_UNIT,
}))}
formatValue={kg}
emptyText="Noch keine Fütterungen erfasst."
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Futterverbrauch pro Saison</CardTitle>
</CardHeader>
<CardContent>
<StatBarList
items={sortedRecordEntries(data.bySeason).map(([year, value]) => ({
label: year,
value,
unit: FEED_UNIT,
}))}
formatValue={kg}
emptyText="Noch keine Fütterungen erfasst."
/>
</CardContent>
</Card>
</div>
)}
{(data) => {
// One block per unit: litres and kilograms are never added up.
const units = Object.entries(
data.byUnit ?? { [FEED_UNIT]: { byColony: data.byColony, bySeason: data.bySeason } },
);
return (
<div className="flex flex-col gap-4">
<PanelHint>
Summe der eingetragenen Futtermengen, getrennt nach Einheit – so wie sie bei der
Fütterung erfasst wurden.
</PanelHint>
{units.length === 0 ? (
<p className="text-sm text-muted-foreground">Noch keine Fütterungen erfasst.</p>
) : null}
{units.map(([unit, totals]) => (
<div key={unit} className="flex flex-col gap-4">
<Card>
<CardHeader>
<CardTitle>Futterverbrauch pro Volk ({unit})</CardTitle>
</CardHeader>
<CardContent>
<StatBarList
items={Object.entries(totals.byColony)
.sort(([, a], [, b]) => b - a)
.slice(0, 10)
.map(([colonyId, value]) => ({
label: colonyLabels.get(colonyId) ?? colonyId,
value,
unit,
}))}
formatValue={kg}
emptyText="Noch keine Fütterungen erfasst."
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Futterverbrauch pro Saison ({unit})</CardTitle>
</CardHeader>
<CardContent>
<StatBarList
items={sortedRecordEntries(totals.bySeason).map(([year, value]) => ({
label: year,
value,
unit,
}))}
formatValue={kg}
emptyText="Noch keine Fütterungen erfasst."
/>
</CardContent>
</Card>
</div>
))}
</div>
);
}}
</QueryState>
);
}