From a5cac16924db3fcd2256b9e7c02abbd3d3ea8097 Mon Sep 17 00:00:00 2001 From: Nemo Date: Tue, 24 Mar 2026 16:09:21 +0800 Subject: [PATCH] fix: tab stack reset, GPS optional for install, status picker mutation fix --- app/(app)/_layout.tsx | 14 +++++--- app/(app)/tasks/[id].tsx | 70 ++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/app/(app)/_layout.tsx b/app/(app)/_layout.tsx index 34984b7..6374074 100644 --- a/app/(app)/_layout.tsx +++ b/app/(app)/_layout.tsx @@ -29,9 +29,12 @@ export default function AppLayout() { /> }} + options={{ title: 'Clients', tabBarIcon: ({ color }) => , unmountOnBlur: true }} listeners={({ navigation }: any) => ({ - tabPress: () => { navigation.navigate('clients', { screen: 'index' }); }, + tabPress: (e) => { + e.preventDefault(); + navigation.reset({ index: 0, routes: [{ name: 'clients' }] }); + }, })} /> }} + options={{ title: 'Tickets', tabBarIcon: ({ color }) => , unmountOnBlur: true }} listeners={({ navigation }: any) => ({ - tabPress: () => { navigation.navigate('tasks', { screen: 'index' }); }, + tabPress: (e) => { + e.preventDefault(); + navigation.reset({ index: 0, routes: [{ name: 'tasks' }] }); + }, })} /> { + mutationFn: async ({ status, activationTicket, subId }: { status: string; activationTicket: boolean; subId?: string }) => { await api.patch(`/api/v1/tickets/${id}`, { status }); // If this is an activation ticket being RESOLVED → activate subscription - if ((status === 'RESOLVED' || status === 'CLOSED') && isActivationTicket) { - const sub = clientDetail?.subscriptions?.[0]; - if (sub?.id && sub?.status !== 'ACTIVE') { - await api.patch(`/api/v1/subscriptions/${sub.id}`, { status: 'ACTIVE' }).catch(() => {}); - } + if ((status === 'RESOLVED' || status === 'CLOSED') && activationTicket && subId) { + await api.patch(`/api/v1/subscriptions/${subId}`, { status: 'ACTIVE' }).catch(() => {}); } const who = user?.firstName ?? 'Staff'; await api.post(`/api/v1/tickets/${id}/messages`, { @@ -107,7 +104,10 @@ export default function TicketDetailScreen() { await refetchClient().catch(() => {}); await refetchInvoices().catch(() => {}); }, - onError: () => Alert.alert('Error', 'Could not update status.'), + onError: (e: any) => { + const msg = e?.response?.data?.message ?? 'Could not update status.'; + Alert.alert('Error', Array.isArray(msg) ? msg.join('\n') : msg); + }, }); const captureLocation = async () => { @@ -128,20 +128,13 @@ export default function TicketDetailScreen() { }; const confirmInstallation = async () => { - if (!coords) { - Alert.alert('Location Required', 'Please capture the installation coordinates before confirming.', [ - { text: 'Cancel', style: 'cancel' }, - { text: 'Capture Now', onPress: captureLocation }, - ]); - return; - } setInstConfirming(true); try { // 1. Resolve the ticket await api.patch(`/api/v1/tickets/${id}`, { status: 'RESOLVED' }); - // 2. Update client location with recorded coordinates - if (ticket?.clientId) { + // 2. Update client location with recorded coordinates (skip if GPS unavailable) + if (ticket?.clientId && coords) { await api.patch(`/api/v1/clients/${ticket.clientId}`, { lat: coords.lat, lng: coords.lng, @@ -149,7 +142,7 @@ export default function TicketDetailScreen() { } // 3. Log activity comment - const coordStr = `${coords.lat.toFixed(6)}, ${coords.lng.toFixed(6)}`; + const coordStr = coords ? `${coords.lat.toFixed(6)}, ${coords.lng.toFixed(6)}` : 'Not captured'; const note = instNotes.trim() ? `Installation confirmed. Location recorded: ${coordStr}. Notes: ${instNotes.trim()}` : `Installation confirmed. Location recorded: ${coordStr}`; @@ -468,26 +461,37 @@ export default function TicketDetailScreen() { - Alert.alert( - 'Confirm Installation', - `Mark this installation as complete?\n\nLocation: ${coords ? `${coords.lat.toFixed(5)}, ${coords.lng.toFixed(5)}` : 'Not captured'}\n\nThis will update the client's location and resolve the ticket.`, - [ - { text: 'Cancel', style: 'cancel' }, - { text: 'Confirm', onPress: confirmInstallation }, - ] - ) - } - disabled={instConfirming || !coords} + onPress={() => { + if (!coords) { + Alert.alert( + 'Location Not Captured', + 'Location not captured — are you sure you want to proceed without GPS coordinates?', + [ + { text: 'Cancel', style: 'cancel' }, + { text: 'Confirm Without Location', onPress: confirmInstallation }, + ] + ); + } else { + Alert.alert( + 'Confirm Installation', + `Mark this installation as complete?\n\nLocation: ${coords.lat.toFixed(5)}, ${coords.lng.toFixed(5)}\n\nThis will update the client's location and resolve the ticket.`, + [ + { text: 'Cancel', style: 'cancel' }, + { text: 'Confirm', onPress: confirmInstallation }, + ] + ); + } + }} + disabled={instConfirming} activeOpacity={0.8} > {instConfirming ? : - {coords ? '✓ Mark Installation Complete' : 'Capture Location First'} + ✓ Mark Installation Complete } @@ -643,7 +647,11 @@ export default function TicketDetailScreen() { ); return; } - updateStatus.mutate(s); + updateStatus.mutate({ + status: s, + activationTicket: isActivationTicket, + subId: clientDetail?.subscriptions?.[0]?.id, + }); }} disabled={isActive || updateStatus.isPending} style={{