diff --git a/apps/mobile/src/app/memory.tsx b/apps/mobile/src/app/memory.tsx
index 5112535..9676bd0 100644
--- a/apps/mobile/src/app/memory.tsx
+++ b/apps/mobile/src/app/memory.tsx
@@ -51,19 +51,27 @@ export default function MemoryScreen() {
mutationFn: (id: string) =>
api(`/v1/me/memory/${id}`, { method: "PATCH", body: { verified: true } }),
onSuccess: invalidate,
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const pause = useMutation({
mutationFn: ({ id, paused }: { id: string; paused: boolean }) =>
api(`/v1/me/memory/${id}`, { method: "PATCH", body: { paused } }),
onSuccess: invalidate,
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const remove = useMutation({
mutationFn: (id: string) => api(`/v1/me/memory/${id}`, { method: "DELETE" }),
onSuccess: invalidate,
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const removeAll = useMutation({
mutationFn: () => api("/v1/me/memory", { method: "DELETE" }),
onSuccess: invalidate,
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
if (query.isLoading) return ;
diff --git a/apps/mobile/src/app/profile.tsx b/apps/mobile/src/app/profile.tsx
index f70d90f..7a1c4d2 100644
--- a/apps/mobile/src/app/profile.tsx
+++ b/apps/mobile/src/app/profile.tsx
@@ -73,15 +73,21 @@ export default function ProfileScreen() {
const togglePrecision = useMutation({
mutationFn: (mode: string) => api("/v1/me", { method: "PATCH", body: { precisionMode: mode } }),
onSuccess: () => void queryClient.invalidateQueries({ queryKey: ["me"] }),
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const deleteAccount = useMutation({
mutationFn: () => api("/v1/me", { method: "DELETE" }),
onSuccess: () => void logout().then(() => router.replace("/(auth)/login")),
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const resend = useMutation({
mutationFn: () => api("/v1/auth/resend-verification", { method: "POST" }),
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
// Språkval (i18n M4): sparas i backend-preferenserna + lokalt, byter direkt.
@@ -96,6 +102,8 @@ export default function ProfileScreen() {
await persistLanguageTag(languageTag);
await queryClient.invalidateQueries();
},
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
if (me.isLoading) return ;
diff --git a/apps/mobile/src/app/recipe/[id].tsx b/apps/mobile/src/app/recipe/[id].tsx
index ad8ffe7..89bfcc7 100644
--- a/apps/mobile/src/app/recipe/[id].tsx
+++ b/apps/mobile/src/app/recipe/[id].tsx
@@ -83,12 +83,16 @@ export default function RecipeScreen() {
mutationFn: (isFavorite: boolean) =>
api(`/v1/recipes/${id}/favorite`, { method: isFavorite ? "DELETE" : "POST" }),
onSuccess: () => void queryClient.invalidateQueries({ queryKey: ["recipe", id] }),
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const rate = useMutation({
mutationFn: (stars: number) =>
api(`/v1/recipes/${id}/rate`, { method: "POST", body: { stars, feedbackTags: [] } }),
onSuccess: () => void queryClient.invalidateQueries({ queryKey: ["recipe", id] }),
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
if (query.isLoading) return ;
diff --git a/apps/mobile/src/app/reconciliation.tsx b/apps/mobile/src/app/reconciliation.tsx
index f0435b5..71dd1c0 100644
--- a/apps/mobile/src/app/reconciliation.tsx
+++ b/apps/mobile/src/app/reconciliation.tsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { ActivityIndicator, View } from "react-native";
+import { ActivityIndicator, Alert, View } from "react-native";
import { router } from "expo-router";
import { useMutation, useQuery } from "@tanstack/react-query";
import { api } from "@/lib/api";
@@ -69,6 +69,8 @@ export default function ReconciliationScreen() {
router.back();
}
},
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
if (query.isLoading) return ;
diff --git a/apps/mobile/src/app/scan-diff-review/[jobId].tsx b/apps/mobile/src/app/scan-diff-review/[jobId].tsx
index d533afe..9cffc0d 100644
--- a/apps/mobile/src/app/scan-diff-review/[jobId].tsx
+++ b/apps/mobile/src/app/scan-diff-review/[jobId].tsx
@@ -1,5 +1,5 @@
import { useMemo, useState } from "react";
-import { View } from "react-native";
+import { Alert, View } from "react-native";
import { router, useLocalSearchParams } from "expo-router";
import { useMutation, useQuery } from "@tanstack/react-query";
import { api } from "@/lib/api";
@@ -52,6 +52,8 @@ export default function ScanDiffReviewScreen() {
onSuccess: () => {
router.back();
},
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const rows = useMemo(() => query.data?.rows ?? [], [query.data]);
diff --git a/apps/mobile/src/app/shopping.tsx b/apps/mobile/src/app/shopping.tsx
index 4e32da8..60c7e34 100644
--- a/apps/mobile/src/app/shopping.tsx
+++ b/apps/mobile/src/app/shopping.tsx
@@ -96,6 +96,8 @@ export default function ShoppingScreen() {
setNewItem("");
invalidate();
},
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const toggle = useMutation({
@@ -105,6 +107,8 @@ export default function ShoppingScreen() {
body: { checked: !item.checked },
}),
onSuccess: invalidate,
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
const complete = useMutation({
@@ -119,6 +123,8 @@ export default function ShoppingScreen() {
invalidate();
Alert.alert(t("shopping.completedTitle"), t("shopping.completedBody", { count: added }));
},
+ onError: (err) =>
+ Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
});
if (lists.isLoading || list.isLoading) return ;