feat(frontend): Toast-Bestaetigungen fuer Schnellerfassung

Sonner-Toaster global eingebunden. Erfolgs-Toast auf allen sechs
Schnellerfassungs-Formularen (Durchsicht, Varroa, Behandlung,
Fuetterung, Aufgabe, Ernte) - ohne Toast blieb nach dem Speichern
und Wegnavigieren keine sichtbare Bestaetigung, dass die Eingabe
gespeichert wurde. Wichtig fuer klares Feedback bei zeitkritischer
Erfassung am Bienenstand.
This commit is contained in:
Nick Szaunig committed 2026-08-23 06:24:14 +02:00
1 parent ecb3afe1f5
commit 8080a7f5ec
7 files changed
+14

No files matched your search

@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchColonies } from "@/lib/colonies/api"; import { fetchColonies } from "@/lib/colonies/api";
import { createFeeding } from "@/lib/feedings/api"; import { createFeeding } from "@/lib/feedings/api";
import { FeedType } from "@/lib/feedings/types"; import { FeedType } from "@/lib/feedings/types";
@@ -60,6 +61,7 @@ export default function NewFeedingPage() {
void queryClient.invalidateQueries({ void queryClient.invalidateQueries({
queryKey: ["colonies", feeding.colonyId, "feedings", "summary"], queryKey: ["colonies", feeding.colonyId, "feedings", "summary"],
}); });
toast.success("Fütterung gespeichert");
router.push(`/colonies/${feeding.colonyId}`); router.push(`/colonies/${feeding.colonyId}`);
}, },
onError: () => { onError: () => {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchApiaries } from "@/lib/apiaries/api"; import { fetchApiaries } from "@/lib/apiaries/api";
import { fetchColonies } from "@/lib/colonies/api"; import { fetchColonies } from "@/lib/colonies/api";
import { createHarvest } from "@/lib/harvests/api"; import { createHarvest } from "@/lib/harvests/api";
@@ -47,6 +48,7 @@ export default function NewHarvestPage() {
mutationFn: createHarvest, mutationFn: createHarvest,
onSuccess: (harvest) => { onSuccess: (harvest) => {
void queryClient.invalidateQueries({ queryKey: ["harvests"] }); void queryClient.invalidateQueries({ queryKey: ["harvests"] });
toast.success("Ernte gespeichert");
router.push(`/harvests/${harvest.id}`); router.push(`/harvests/${harvest.id}`);
}, },
onError: () => { onError: () => {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchColonies } from "@/lib/colonies/api"; import { fetchColonies } from "@/lib/colonies/api";
import { createInspection } from "@/lib/inspections/api"; import { createInspection } from "@/lib/inspections/api";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -51,6 +52,7 @@ export default function NewInspectionPage() {
void queryClient.invalidateQueries({ void queryClient.invalidateQueries({
queryKey: ["colonies", inspection.colonyId, "inspections"], queryKey: ["colonies", inspection.colonyId, "inspections"],
}); });
toast.success("Durchsicht gespeichert");
router.push(`/colonies/${inspection.colonyId}`); router.push(`/colonies/${inspection.colonyId}`);
}, },
onError: () => { onError: () => {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { createTask } from "@/lib/tasks/api"; import { createTask } from "@/lib/tasks/api";
import { TaskPriority } from "@/lib/tasks/types"; import { TaskPriority } from "@/lib/tasks/types";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -33,6 +34,7 @@ export default function NewTaskPage() {
mutationFn: createTask, mutationFn: createTask,
onSuccess: () => { onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: ["tasks"] }); void queryClient.invalidateQueries({ queryKey: ["tasks"] });
toast.success("Aufgabe angelegt");
router.push("/tasks"); router.push("/tasks");
}, },
onError: () => { onError: () => {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchColonies } from "@/lib/colonies/api"; import { fetchColonies } from "@/lib/colonies/api";
import { createTreatment } from "@/lib/treatments/api"; import { createTreatment } from "@/lib/treatments/api";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@@ -48,6 +49,7 @@ export default function NewTreatmentPage() {
void queryClient.invalidateQueries({ void queryClient.invalidateQueries({
queryKey: ["colonies", treatment.colonyId, "treatments"], queryKey: ["colonies", treatment.colonyId, "treatments"],
}); });
toast.success("Behandlung gespeichert");
router.push(`/colonies/${treatment.colonyId}`); router.push(`/colonies/${treatment.colonyId}`);
}, },
onError: () => { onError: () => {
@@ -3,6 +3,7 @@
import { FormEvent, useState } from "react"; import { FormEvent, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { fetchColonies } from "@/lib/colonies/api"; import { fetchColonies } from "@/lib/colonies/api";
import { createVarroaMeasurement } from "@/lib/varroa/api"; import { createVarroaMeasurement } from "@/lib/varroa/api";
import { VarroaMethod } from "@/lib/varroa/types"; import { VarroaMethod } from "@/lib/varroa/types";
@@ -56,6 +57,7 @@ export default function NewVarroaMeasurementPage() {
void queryClient.invalidateQueries({ void queryClient.invalidateQueries({
queryKey: ["colonies", measurement.colonyId, "varroa-measurements"], queryKey: ["colonies", measurement.colonyId, "varroa-measurements"],
}); });
toast.success("Varroamessung gespeichert");
router.push(`/colonies/${measurement.colonyId}`); router.push(`/colonies/${measurement.colonyId}`);
}, },
onError: () => { onError: () => {
+2
View File
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Space_Grotesk, Inter, IBM_Plex_Mono } from "next/font/google"; import { Space_Grotesk, Inter, IBM_Plex_Mono } from "next/font/google";
import "./globals.css"; import "./globals.css";
import { Providers } from "./providers"; import { Providers } from "./providers";
import { Toaster } from "@/components/ui/sonner";
const spaceGrotesk = Space_Grotesk({ const spaceGrotesk = Space_Grotesk({
variable: "--font-heading", variable: "--font-heading",
@@ -33,6 +34,7 @@ export default function RootLayout({ children }: LayoutProps<"/">) {
> >
<body className="min-h-full flex flex-col"> <body className="min-h-full flex flex-col">
<Providers>{children}</Providers> <Providers>{children}</Providers>
<Toaster position="top-right" richColors />
</body> </body>
</html> </html>
); );