All files / src/hooks useEventPhotos.ts

100% Statements 15/15
100% Branches 3/3
100% Functions 8/8
100% Lines 15/15

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                    1x 6x   2x                       1x 5x   5x   3x 2x 2x           2x         1x 5x   5x 3x   2x        
/**
 * Hooks for event photo management.
 * Story 10.21: Event Photos Gallery
 */
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { eventApiClient } from '@/services/eventApiClient';
import type { components } from '@/types/generated/event-media-api.types';
 
type EventPhotoUploadRequest = components['schemas']['EventPhotoUploadRequest'];
 
export const useEventPhotos = (eventCode: string, enabled = true) => {
  return useQuery({
    queryKey: ['event-photos', eventCode],
    queryFn: () => eventApiClient.listEventPhotos(eventCode),
    enabled: enabled && !!eventCode,
  });
};
 
/**
 * 3-phase upload mutation:
 * 1. POST /photos/upload-url → { photoId, uploadUrl, s3Key }
 * 2. PUT to S3 directly with the file
 * 3. POST /photos/confirm → EventPhotoResponse
 * On success: invalidate ['event-photos', eventCode]
 */
export const useUploadEventPhoto = (eventCode: string) => {
  const queryClient = useQueryClient();
 
  return useMutation({
    mutationFn: async ({ file, request }: { file: File; request: EventPhotoUploadRequest }) => {
      const uploadResponse = await eventApiClient.requestEventPhotoUploadUrl(eventCode, request);
      await eventApiClient.uploadPhotoToS3(uploadResponse.uploadUrl, file);
      return eventApiClient.confirmEventPhotoUpload(eventCode, {
        photoId: uploadResponse.photoId,
        s3Key: uploadResponse.s3Key,
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['event-photos', eventCode] });
    },
  });
};
 
export const useDeleteEventPhoto = (eventCode: string) => {
  const queryClient = useQueryClient();
 
  return useMutation({
    mutationFn: (photoId: string) => eventApiClient.deleteEventPhoto(eventCode, photoId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['event-photos', eventCode] });
    },
  });
};