Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 10x 90x 90x 90x 7x 6x 6x 6x 10x 93x 93x 8x 8x 8x 8x 2x 8x 5x 5x 5x 3x 1x | /**
* usePartnerMutations Hooks (Story 2.8.3)
*
* React Query mutation hooks for partner create/update operations with optimistic updates
* AC 8 (Create Partnership), AC 9 (Edit Partnership)
*/
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { createPartner, updatePartner } from '@/services/api/partnerApi';
import type {
PartnerResponse,
CreatePartnerRequest,
UpdatePartnerRequest,
} from '@/services/api/partnerApi';
/**
* Create new partnership mutation
*
* Features:
* - Automatic cache invalidation of partners list and statistics
* - Navigation to detail view on success
* - Error handling with correlation IDs
*
* @returns Mutation hook for creating partnerships
*/
export const useCreatePartner = () => {
const queryClient = useQueryClient();
const navigate = useNavigate();
return useMutation({
mutationFn: (data: CreatePartnerRequest) => createPartner(data),
onSuccess: (data) => {
// Invalidate partners list and statistics to refetch with new partnership
queryClient.invalidateQueries({ queryKey: ['partners'] });
queryClient.invalidateQueries({ queryKey: ['partner-statistics'] });
// Navigate to detail view
navigate(`/organizer/partners/${data.companyName}`);
},
});
};
/**
* Update existing partnership mutation with optimistic updates
*
* Features:
* - Optimistic UI updates (immediate feedback)
* - Rollback on error
* - Cache invalidation of both list and detail
* - Partial update support (only changed fields)
*
* @returns Mutation hook for updating partnerships
*/
export const useUpdatePartner = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ companyName, data }: { companyName: string; data: UpdatePartnerRequest }) =>
updatePartner(companyName, data),
// Optimistic update (AC 9 - immediate UI feedback)
onMutate: async ({ companyName, data }) => {
// Cancel any outgoing refetches to prevent overwriting optimistic update
await queryClient.cancelQueries({ queryKey: ['partner', companyName] });
// Snapshot the previous value for rollback
const previousPartner = queryClient.getQueryData(['partner', companyName, undefined]);
// Optimistically update to the new value
if (previousPartner) {
queryClient.setQueryData(['partner', companyName, undefined], (old: PartnerResponse) => ({
...old,
...data,
}));
}
// Return context with snapshot for rollback
return { previousPartner };
},
// On success, invalidate caches to refetch fresh data
onSuccess: (_, { companyName }) => {
queryClient.invalidateQueries({ queryKey: ['partners'] });
queryClient.invalidateQueries({ queryKey: ['partner', companyName] });
queryClient.invalidateQueries({ queryKey: ['partner-statistics'] });
},
// Rollback on error (AC 9 - error handling with rollback)
onError: (_error, { companyName }, context) => {
if (context?.previousPartner) {
queryClient.setQueryData(['partner', companyName, undefined], context.previousPartner);
}
},
});
};
|