import { useCallback } from 'react'; import { usePersSDK } from '../providers/PersSDKProvider'; import type { SignedUrlRequest, FileUploadEntityType } from '@explorins/pers-sdk'; /** * React hook for file operations in the PERS SDK * * Provides methods for generating signed URLs for file uploads and downloads, * media optimization, and secure file access. Supports various entity types * and customizable expiration times. * * @returns File hook with methods for file management * * @example * ```typescript * function FileUploadComponent() { * const { getSignedPutUrl, getSignedGetUrl, optimizeMedia } = useFiles(); * * const uploadFile = async (entityId: string, file: File) => { * try { * const uploadUrl = await getSignedPutUrl( * entityId, * 'profile', * 'jpg' * ); * * // Upload file to the signed URL * await fetch(uploadUrl, { * method: 'PUT', * body: file * }); * * // Get download URL * const downloadUrl = await getSignedGetUrl(entityId, 'profile'); * console.log('File uploaded, download URL:', downloadUrl); * } catch (error) { * console.error('File upload failed:', error); * } * }; * * return uploadFile('user-123', e.target.files[0])} />; * } * ``` */ export const useFiles = () => { const { sdk, isInitialized } = usePersSDK(); /** * Generates a signed URL for uploading files to cloud storage * * @param entityId - Unique identifier of the entity the file belongs to * @param entityType - Type of entity ('profile', 'business', 'campaign', etc.) * @param fileExtension - File extension without the dot (e.g., 'jpg', 'png') * @returns Promise resolving to signed upload URL * @throws Error if SDK is not initialized * * @example * ```typescript * const { getSignedPutUrl } = useFiles(); * const uploadUrl = await getSignedPutUrl('user-123', 'profile', 'jpg'); * // Use uploadUrl with PUT request to upload file * ``` */ const getSignedPutUrl = useCallback(async ( entityId: string, entityType: FileUploadEntityType, fileExtension: string ): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.files.getSignedPutUrl(entityId, entityType, fileExtension); return result; } catch (error) { console.error('Failed to generate signed put URL:', error); throw error; } }, [sdk, isInitialized]); /** * Generates a signed URL for downloading files from cloud storage * * @param entityId - Unique identifier of the entity the file belongs to * @param entityType - Type of entity ('profile', 'business', 'campaign', etc.) * @param expireSeconds - Optional expiration time in seconds (default varies by implementation) * @returns Promise resolving to signed download URL * @throws Error if SDK is not initialized * * @example * ```typescript * const { getSignedGetUrl } = useFiles(); * const downloadUrl = await getSignedGetUrl('user-123', 'profile', 3600); // 1 hour expiry * // Use downloadUrl to display or download the file * ``` */ const getSignedGetUrl = useCallback(async ( entityId: string, entityType: FileUploadEntityType, expireSeconds?: number ): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.files.getSignedGetUrl(entityId, entityType, expireSeconds); return result; } catch (error) { console.error('Failed to generate signed get URL:', error); throw error; } }, [sdk, isInitialized]); const getSignedUrl = useCallback(async (request: SignedUrlRequest): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.files.getSignedUrl(request); return result; } catch (error) { console.error('Failed to generate signed URL:', error); throw error; } }, [sdk, isInitialized]); const optimizeMedia = useCallback(async (url: string, width?: number, height?: number): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { const result = await sdk.files.optimizeMedia(url, width, height); return result; } catch (error) { console.error('Failed to optimize media:', error); throw error; } }, [sdk, isInitialized]); return { getSignedPutUrl, getSignedGetUrl, getSignedUrl, optimizeMedia, isAvailable: isInitialized && !!sdk?.files, }; }; export type FileHook = ReturnType;