From 491daace861ff90b50d7dba43daf7e8c4023d853 Mon Sep 17 00:00:00 2001 From: "Sven (AAMOS AI)" Date: Fri, 14 Aug 2026 18:03:36 +0700 Subject: [PATCH] =?UTF-8?q?fix(mobile):=20onError=20p=C3=A5=2015=20mutatio?= =?UTF-8?q?ner=20=E2=80=93=20inga=20tysta=20miss=20(MIKRO=2052)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mobile/src/app/memory.tsx | 8 ++++++++ apps/mobile/src/app/profile.tsx | 8 ++++++++ apps/mobile/src/app/recipe/[id].tsx | 4 ++++ apps/mobile/src/app/reconciliation.tsx | 4 +++- apps/mobile/src/app/scan-diff-review/[jobId].tsx | 4 +++- apps/mobile/src/app/shopping.tsx | 6 ++++++ 6 files changed, 32 insertions(+), 2 deletions(-) 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 ;