fix: surface remaining silent mutation failures
Four more mutations had no error feedback: equipment condition change, task completion, and notification mark-as-read all failed silently. More importantly, the offline sync badge computed a result.failed count from syncPendingInspections() but never displayed it - an entry rejected by the server (e.g. a validation rule) would sit in the offline queue indefinitely with zero indication to the beekeeper why it never syncs. Both the failed-count and outright sync-mutation rejection now surface a toast. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
997dadfaaa
commit
dfb4de81f8
4 files changed
+13
No files matched your search
@@ -3,6 +3,7 @@
|
|||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import { Wrench } from "lucide-react";
|
import { Wrench } from "lucide-react";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { toast } from "sonner";
|
||||||
import { fetchEquipment, updateEquipment } from "@/lib/equipment/api";
|
import { fetchEquipment, updateEquipment } from "@/lib/equipment/api";
|
||||||
import { EquipmentCondition } from "@/lib/equipment/types";
|
import { EquipmentCondition } from "@/lib/equipment/types";
|
||||||
import { EQUIPMENT_CONDITIONS, EQUIPMENT_CONDITION_LABELS } from "@/lib/equipment/labels";
|
import { EQUIPMENT_CONDITIONS, EQUIPMENT_CONDITION_LABELS } from "@/lib/equipment/labels";
|
||||||
@@ -32,6 +33,7 @@ export default function EquipmentDetailPage() {
|
|||||||
void queryClient.invalidateQueries({ queryKey: ["equipment", params.id] });
|
void queryClient.invalidateQueries({ queryKey: ["equipment", params.id] });
|
||||||
void queryClient.invalidateQueries({ queryKey: ["equipment"] });
|
void queryClient.invalidateQueries({ queryKey: ["equipment"] });
|
||||||
},
|
},
|
||||||
|
onError: () => toast.error("Zustand konnte nicht gespeichert werden"),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useState } from "react";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { ListTodo } from "lucide-react";
|
import { ListTodo } from "lucide-react";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { toast } from "sonner";
|
||||||
import { completeTask, fetchTasks } from "@/lib/tasks/api";
|
import { completeTask, fetchTasks } from "@/lib/tasks/api";
|
||||||
import { TaskPriority, TaskStatus } from "@/lib/tasks/types";
|
import { TaskPriority, TaskStatus } from "@/lib/tasks/types";
|
||||||
import { TASK_PRIORITIES, TASK_PRIORITY_LABELS, TASK_STATUS_LABELS } from "@/lib/tasks/labels";
|
import { TASK_PRIORITIES, TASK_PRIORITY_LABELS, TASK_STATUS_LABELS } from "@/lib/tasks/labels";
|
||||||
@@ -40,6 +41,7 @@ export default function TasksPage() {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
void queryClient.invalidateQueries({ queryKey: ["tasks"] });
|
void queryClient.invalidateQueries({ queryKey: ["tasks"] });
|
||||||
},
|
},
|
||||||
|
onError: () => toast.error("Aufgabe konnte nicht erledigt werden"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const [now] = useState(() => Date.now());
|
const [now] = useState(() => Date.now());
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { Bell } from "lucide-react";
|
import { Bell } from "lucide-react";
|
||||||
|
import { toast } from "sonner";
|
||||||
import { fetchNotifications, markNotificationRead } from "@/lib/notifications/api";
|
import { fetchNotifications, markNotificationRead } from "@/lib/notifications/api";
|
||||||
import { Notification, NotificationPriority } from "@/lib/notifications/types";
|
import { Notification, NotificationPriority } from "@/lib/notifications/types";
|
||||||
import { Badge, badgeVariants } from "@/components/ui/badge";
|
import { Badge, badgeVariants } from "@/components/ui/badge";
|
||||||
@@ -41,6 +42,7 @@ export function NotificationBell() {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
void queryClient.invalidateQueries({ queryKey: ["notifications"] });
|
void queryClient.invalidateQueries({ queryKey: ["notifications"] });
|
||||||
},
|
},
|
||||||
|
onError: () => toast.error("Benachrichtigung konnte nicht als gelesen markiert werden"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const unreadCount = notifications?.filter((notification) => !notification.read).length ?? 0;
|
const unreadCount = notifications?.filter((notification) => !notification.read).length ?? 0;
|
||||||
|
|||||||
@@ -26,7 +26,14 @@ export function OfflineSyncBadge() {
|
|||||||
if (result.synced > 0) {
|
if (result.synced > 0) {
|
||||||
toast.success(`${result.synced} Eintrag/Einträge synchronisiert`);
|
toast.success(`${result.synced} Eintrag/Einträge synchronisiert`);
|
||||||
}
|
}
|
||||||
|
if (result.failed > 0) {
|
||||||
|
toast.error(
|
||||||
|
`${result.failed} Eintrag/Einträge konnten nicht synchronisiert werden und bleiben in der Warteschlange`,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
onError: () =>
|
||||||
|
toast.error("Synchronisierung fehlgeschlagen - wird beim nächsten Versuch erneut versucht"),
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in new issue
Block a user