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;