fix: show an error toast when editing any entity fails

Nearly every *-edit-dialog.tsx and *-edit-card.tsx in the app - the
save mutation for editing a colony, queen, treatment, inspection,
feeding, varroa measurement, swarm control check, harvest, extraction
(both variants), honey batch, bottling batch, task, stock item,
storage container, or product - had an onSuccess handler but no
onError. A failed save (a validation error, including several added
earlier this session, a permission error, a network hiccup) produced
no feedback at all: no toast, no inline message, the dialog just sat
there having silently done nothing. The user's most likely read on
that is "it saved," when it didn't.

Added the same onError: () => toast.error("<Entity> konnte nicht
gespeichert werden") pattern already used elsewhere in the app (e.g.
apiary deactivate/reactivate) to every one of these mutations. Also
covers assign-colony-dialog.tsx, which is the exact spot where the
queen-availability guard added earlier this session would otherwise
have failed with zero visible feedback.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Sonnet 5 committed 2026-09-09 11:22:11 +02:00
1 parent 96207d0096
commit b4caa2ad5a
18 files changed
+35

No files matched your search

@@ -43,6 +43,7 @@ export function ApiaryEditCard({ apiary }: { apiary: Apiary }) {
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: ["apiaries"] });
},
onError: () => toast.error("Bienenstand konnte nicht gespeichert werden"),
});
const deactivateMutation = useMutation({
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateBottlingBatch } from "@/lib/bottling/api";
import { BottlingBatch } from "@/lib/bottling/types";
import { fetchProducts } from "@/lib/products/api";
@@ -53,6 +54,7 @@ export function BottlingEditDialog({ bottlingBatch }: { bottlingBatch: BottlingB
});
setOpen(false);
},
onError: () => toast.error("Abfüllung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Layers } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateColony } from "@/lib/colonies/api";
import { Colony, ColonyCondition, ColonyStatus, ColonyType } from "@/lib/colonies/types";
import {
@@ -108,6 +109,7 @@ export function ColonyEditCard({ colony }: { colony: Colony }) {
void queryClient.invalidateQueries({ queryKey: ["colonies"] });
void queryClient.invalidateQueries({ queryKey: ["colonies", colony.id] });
},
onError: () => toast.error("Volk konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateFeeding } from "@/lib/feedings/api";
import { Feeding, FeedType } from "@/lib/feedings/types";
import { FEED_TYPES, FEED_TYPE_LABELS } from "@/lib/feedings/labels";
@@ -53,6 +54,7 @@ export function FeedingEditDialog({ feeding }: { feeding: Feeding }) {
});
setOpen(false);
},
onError: () => toast.error("Fütterung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateInspection } from "@/lib/inspections/api";
import { Inspection } from "@/lib/inspections/types";
@@ -90,6 +91,7 @@ export function InspectionEditDialog({ inspection }: { inspection: Inspection })
});
setOpen(false);
},
onError: () => toast.error("Durchsicht konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateSwarmControlCheck } from "@/lib/swarm-control/api";
import { SWARM_ACTION_LABELS, SWARM_MOOD_LABELS } from "@/lib/swarm-control/labels";
import { SwarmControlAction, SwarmControlCheck, SwarmMood } from "@/lib/swarm-control/types";
@@ -53,6 +54,7 @@ export function SwarmControlEditDialog({ check }: { check: SwarmControlCheck })
});
setOpen(false);
},
onError: () => toast.error("Schwarmkontrolle konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateTreatment } from "@/lib/treatments/api";
import { Treatment } from "@/lib/treatments/types";
import { Button } from "@/components/ui/button";
@@ -55,6 +56,7 @@ export function TreatmentEditDialog({ treatment }: { treatment: Treatment }) {
});
setOpen(false);
},
onError: () => toast.error("Behandlung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateVarroaMeasurement } from "@/lib/varroa/api";
import { VarroaMeasurement, VarroaMethod } from "@/lib/varroa/types";
import { VARROA_METHODS, VARROA_METHOD_LABELS } from "@/lib/varroa/labels";
@@ -57,6 +58,7 @@ export function VarroaEditDialog({ measurement }: { measurement: VarroaMeasureme
});
setOpen(false);
},
onError: () => toast.error("Varroamessung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateExtraction } from "@/lib/extractions/api";
import { Extraction } from "@/lib/extractions/types";
import { Button } from "@/components/ui/button";
@@ -41,6 +42,7 @@ export function ExtractionEditDialog({ extraction }: { extraction: Extraction })
void queryClient.invalidateQueries({ queryKey: ["extractions", extraction.id] });
setOpen(false);
},
onError: () => toast.error("Schleuderung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateHarvest } from "@/lib/harvests/api";
import { Harvest } from "@/lib/harvests/types";
import { Button } from "@/components/ui/button";
@@ -43,6 +44,7 @@ export function HarvestEditDialog({ harvest }: { harvest: Harvest }) {
void queryClient.invalidateQueries({ queryKey: ["harvests", harvest.id] });
setOpen(false);
},
onError: () => toast.error("Ernte konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchExtraction, updateExtraction } from "@/lib/extractions/api";
import { Extraction } from "@/lib/extractions/types";
import { Button } from "@/components/ui/button";
@@ -54,6 +55,7 @@ function ExtractionEditForm({
});
onSaved();
},
onError: () => toast.error("Schleuderung konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateHoneyBatch } from "@/lib/honey-batches/api";
import { HoneyBatch } from "@/lib/honey-batches/types";
import { Button } from "@/components/ui/button";
@@ -36,6 +37,7 @@ export function HoneyBatchEditDialog({ honeyBatch }: { honeyBatch: HoneyBatch })
void queryClient.invalidateQueries({ queryKey: ["honey-batches"] });
setOpen(false);
},
onError: () => toast.error("Honigcharge konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateProduct } from "@/lib/products/api";
import { Product } from "@/lib/products/types";
import { Button } from "@/components/ui/button";
@@ -42,6 +43,7 @@ export function EditProductDialog({ product }: { product: Product }) {
void queryClient.invalidateQueries({ queryKey: ["products"] });
setOpen(false);
},
onError: () => toast.error("Produkt konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -2,6 +2,7 @@
import { FormEvent, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { assignQueenColony } from "@/lib/queens/api";
import { QUEEN_UNAVAILABLE_STATUSES } from "@/lib/queens/labels";
import { QueenStatus } from "@/lib/queens/types";
@@ -44,6 +45,7 @@ export function AssignColonyDialog({
void queryClient.invalidateQueries({ queryKey: ["queens", queenId, "history"] });
setOpen(false);
},
onError: () => toast.error("Volk konnte nicht zugewiesen werden"),
});
return (
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Crown } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchQueens, updateQueen } from "@/lib/queens/api";
import { suggestMarkingColorForYear } from "@/lib/queens/marking-color";
import { Queen, QueenStatus } from "@/lib/queens/types";
@@ -80,6 +81,7 @@ export function QueenEditCard({ queen }: { queen: Queen }) {
void queryClient.invalidateQueries({ queryKey: ["queens"] });
void queryClient.invalidateQueries({ queryKey: ["queens", queen.id] });
},
onError: () => toast.error("Königin konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateStockItem } from "@/lib/storage/api";
import { StockCategory, StockItem } from "@/lib/storage/types";
import { STOCK_CATEGORIES, STOCK_CATEGORY_LABELS } from "@/lib/storage/labels";
@@ -48,6 +49,7 @@ export function EditStockItemDialog({ item }: { item: StockItem }) {
void queryClient.invalidateQueries({ queryKey: ["stock-items"] });
setOpen(false);
},
onError: () => toast.error("Lagerartikel konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateStorageContainer } from "@/lib/storage/api";
import { StorageContainer } from "@/lib/storage/types";
import { Button } from "@/components/ui/button";
@@ -35,6 +36,7 @@ export function EditStorageContainerDialog({ container }: { container: StorageCo
void queryClient.invalidateQueries({ queryKey: ["storage-containers"] });
setOpen(false);
},
onError: () => toast.error("Lagerbehälter konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react";
import { Pencil } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { updateTask } from "@/lib/tasks/api";
import { Task, TaskPriority } from "@/lib/tasks/types";
import { TASK_PRIORITIES, TASK_PRIORITY_LABELS } from "@/lib/tasks/labels";
@@ -57,6 +58,7 @@ export function TaskEditDialog({ task }: { task: Task }) {
void queryClient.invalidateQueries({ queryKey: ["tasks"] });
setOpen(false);
},
onError: () => toast.error("Aufgabe konnte nicht gespeichert werden"),
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {