Unify toast accept path with notification center via useConnections
Toast now uses the same respond() from useConnections hook instead of raw api.put, making both accept surfaces share identical code. Also made respondMutation.onSuccess fire-and-forget to prevent invalidation errors from surfacing as mutation failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5828bbf8e2
commit
60281caa64
@ -3,11 +3,13 @@ import { toast } from 'sonner';
|
|||||||
import { Check, X, Bell, UserPlus } from 'lucide-react';
|
import { Check, X, Bell, UserPlus } from 'lucide-react';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { useNotifications } from '@/hooks/useNotifications';
|
import { useNotifications } from '@/hooks/useNotifications';
|
||||||
import api, { getErrorMessage } from '@/lib/api';
|
import { useConnections } from '@/hooks/useConnections';
|
||||||
|
import { getErrorMessage } from '@/lib/api';
|
||||||
import type { AppNotification } from '@/types';
|
import type { AppNotification } from '@/types';
|
||||||
|
|
||||||
export default function NotificationToaster() {
|
export default function NotificationToaster() {
|
||||||
const { notifications, unreadCount } = useNotifications();
|
const { notifications, unreadCount } = useNotifications();
|
||||||
|
const { respond } = useConnections();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const maxSeenIdRef = useRef(0);
|
const maxSeenIdRef = useRef(0);
|
||||||
const initializedRef = useRef(false);
|
const initializedRef = useRef(false);
|
||||||
@ -16,20 +18,15 @@ export default function NotificationToaster() {
|
|||||||
const handleConnectionRespond = useCallback(
|
const handleConnectionRespond = useCallback(
|
||||||
async (requestId: number, action: 'accept' | 'reject', toastId: string | number) => {
|
async (requestId: number, action: 'accept' | 'reject', toastId: string | number) => {
|
||||||
try {
|
try {
|
||||||
await api.put(`/connections/requests/${requestId}/respond`, { action });
|
await respond({ requestId, action });
|
||||||
|
// onSuccess in useConnections already dismisses the custom toast and invalidates caches
|
||||||
|
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
||||||
} 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'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
toast.dismiss(toastId);
|
|
||||||
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
|
||||||
// Fire-and-forget — invalidation errors should not surface as "Failed to respond"
|
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
|
||||||
queryClient.invalidateQueries({ queryKey: ['people'] });
|
|
||||||
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
|
||||||
},
|
},
|
||||||
[queryClient],
|
[respond],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Track unread count changes to force-refetch the list
|
// Track unread count changes to force-refetch the list
|
||||||
|
|||||||
@ -57,14 +57,13 @@ 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: async (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
// Dismiss any lingering Sonner toast for this request
|
// Dismiss any lingering Sonner toast for this request
|
||||||
toast.dismiss(`connection-request-${variables.requestId}`);
|
toast.dismiss(`connection-request-${variables.requestId}`);
|
||||||
await Promise.all([
|
// Fire-and-forget — errors here must not surface as mutation failures
|
||||||
queryClient.invalidateQueries({ queryKey: ['connections'] }),
|
queryClient.invalidateQueries({ queryKey: ['connections'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['people'] }),
|
queryClient.invalidateQueries({ queryKey: ['people'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['notifications'] }),
|
queryClient.invalidateQueries({ queryKey: ['notifications'] });
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user