Fix stale UI after accept: await invalidations, dismiss toasts
- Await all query invalidations in respondMutation/cancelMutation
onSuccess so UI has fresh data before mutation promise resolves
- Use deterministic toast IDs (connection-request-{id}) for Sonner
toasts so they can be dismissed from any accept surface
- Dismiss stale connection toasts in respondMutation.onSuccess
- Fix handleCancel setting resolved before API call completes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b554ba7151
commit
14a77f0f11
@ -38,12 +38,11 @@ export default function ConnectionRequestCard({ request, direction }: Connection
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = async () => {
|
const handleCancel = async () => {
|
||||||
setResolved(true);
|
|
||||||
try {
|
try {
|
||||||
await cancelRequest(request.id);
|
await cancelRequest(request.id);
|
||||||
|
setResolved(true);
|
||||||
toast.success('Request cancelled');
|
toast.success('Request cancelled');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setResolved(false);
|
|
||||||
toast.error(getErrorMessage(err, 'Failed to cancel request'));
|
toast.error(getErrorMessage(err, 'Failed to cancel request'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,9 +19,11 @@ export default function NotificationToaster() {
|
|||||||
await api.put(`/connections/requests/${requestId}/respond`, { action });
|
await api.put(`/connections/requests/${requestId}/respond`, { action });
|
||||||
toast.dismiss(toastId);
|
toast.dismiss(toastId);
|
||||||
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
await Promise.all([
|
||||||
queryClient.invalidateQueries({ queryKey: ['people'] });
|
queryClient.invalidateQueries({ queryKey: ['connections'] }),
|
||||||
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
queryClient.invalidateQueries({ queryKey: ['people'] }),
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['notifications'] }),
|
||||||
|
]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toast.dismiss(toastId);
|
toast.dismiss(toastId);
|
||||||
toast.error(getErrorMessage(err, 'Failed to respond to request'));
|
toast.error(getErrorMessage(err, 'Failed to respond to request'));
|
||||||
@ -109,7 +111,7 @@ export default function NotificationToaster() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
{ duration: 30000 },
|
{ id: `connection-request-${requestId}`, duration: 30000 },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { toast } from 'sonner';
|
||||||
import api from '@/lib/api';
|
import api from '@/lib/api';
|
||||||
import type { Connection, ConnectionRequest, UmbralSearchResponse } from '@/types';
|
import type { Connection, ConnectionRequest, UmbralSearchResponse } from '@/types';
|
||||||
|
|
||||||
@ -46,8 +47,8 @@ export function useConnections() {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
await queryClient.invalidateQueries({ queryKey: ['connections'] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -56,10 +57,14 @@ export function useConnections() {
|
|||||||
const { data } = await api.put(`/connections/requests/${requestId}/respond`, { action });
|
const { data } = await api.put(`/connections/requests/${requestId}/respond`, { action });
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async (_, variables) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
// Dismiss any lingering Sonner toast for this request
|
||||||
queryClient.invalidateQueries({ queryKey: ['people'] });
|
toast.dismiss(`connection-request-${variables.requestId}`);
|
||||||
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
await Promise.all([
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['connections'] }),
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['people'] }),
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['notifications'] }),
|
||||||
|
]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,9 +73,11 @@ export function useConnections() {
|
|||||||
const { data } = await api.put(`/connections/requests/${requestId}/cancel`);
|
const { data } = await api.put(`/connections/requests/${requestId}/cancel`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: async () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
await Promise.all([
|
||||||
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
queryClient.invalidateQueries({ queryKey: ['connections'] }),
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['notifications'] }),
|
||||||
|
]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user