NeoScan_Physician/app/shared/utils/fileUpload.ts
2025-08-20 20:42:33 +05:30

228 lines
5.7 KiB
TypeScript

/*
* File: fileUpload.ts
* Description: Utility functions for handling file uploads in React Native
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
// ============================================================================
// INTERFACES
// ============================================================================
/**
* FileData Interface
*
* Purpose: Defines the structure for file data from image picker
*/
export interface FileData {
uri: string;
name?: string;
type?: string;
size?: number;
}
/**
* UploadFile Interface
*
* Purpose: Defines the structure for file object in FormData
*/
export interface UploadFile {
uri: string;
name: string;
type: string;
}
// ============================================================================
// FILE UPLOAD UTILITIES
// ============================================================================
/**
* Prepare File for Upload
*
* Purpose: Convert FileData to proper UploadFile structure for FormData
*
* @param fileData - File data from image picker
* @param fieldName - Form field name for the file
* @returns Properly formatted UploadFile object
*/
export const prepareFileForUpload = (
fileData: FileData,
fieldName: string = 'file'
): UploadFile => {
// Extract file extension from URI
const uri = fileData.uri;
const fileName = fileData.name || `${fieldName}_${Date.now()}`;
// Determine file extension and MIME type
let fileExtension = 'jpg';
let mimeType = 'image/jpeg';
if (fileData.type) {
// Use provided type
mimeType = fileData.type;
fileExtension = mimeType.split('/')[1] || 'jpg';
} else {
// Extract from URI
const uriParts = uri.split('.');
if (uriParts.length > 1) {
fileExtension = uriParts[uriParts.length - 1].toLowerCase();
// Map extension to MIME type
switch (fileExtension) {
case 'png':
mimeType = 'image/png';
break;
case 'jpeg':
case 'jpg':
mimeType = 'image/jpeg';
break;
case 'gif':
mimeType = 'image/gif';
break;
case 'webp':
mimeType = 'image/webp';
break;
default:
mimeType = 'image/jpeg';
fileExtension = 'jpg';
}
}
}
// Ensure filename has proper extension
const finalFileName = fileName.includes('.')
? fileName
: `${fileName}.${fileExtension}`;
return {
uri,
name: finalFileName,
type: mimeType,
};
};
/**
* Create FormData with File
*
* Purpose: Create FormData object with proper file attachment
*
* @param data - Object containing form fields
* @param fileData - File data to upload
* @param fileFieldName - Form field name for the file
* @returns FormData object ready for upload
*/
export const createFormDataWithFile = (
data: Record<string, any>,
fileData?: FileData,
fileFieldName: string = 'file'
): FormData => {
const formData = new FormData();
// Add regular form fields
Object.keys(data).forEach(key => {
if (data[key] !== null && data[key] !== undefined) {
formData.append(key, String(data[key]));
}
});
// Add file if provided
if (fileData) {
const uploadFile = prepareFileForUpload(fileData, fileFieldName);
formData.append(fileFieldName, uploadFile as any);
}
return formData;
};
/**
* Validate File Type
*
* Purpose: Check if file type is allowed
*
* @param fileData - File data to validate
* @param allowedTypes - Array of allowed MIME types
* @returns Boolean indicating if file type is allowed
*/
export const validateFileType = (
fileData: FileData,
allowedTypes: string[] = ['image/jpeg', 'image/jpg', 'image/png']
): boolean => {
if (!fileData.type) {
// If no type provided, try to determine from URI
const uri = fileData.uri.toLowerCase();
if (uri.includes('.jpg') || uri.includes('.jpeg')) {
return allowedTypes.includes('image/jpeg') || allowedTypes.includes('image/jpg');
}
if (uri.includes('.png')) {
return allowedTypes.includes('image/png');
}
return false;
}
return allowedTypes.includes(fileData.type.toLowerCase());
};
/**
* Validate File Size
*
* Purpose: Check if file size is within limits
*
* @param fileData - File data to validate
* @param maxSizeMB - Maximum file size in MB
* @returns Boolean indicating if file size is acceptable
*/
export const validateFileSize = (
fileData: FileData,
maxSizeMB: number = 10
): boolean => {
if (!fileData.size) {
return true; // Skip validation if size not available
}
const maxSizeBytes = maxSizeMB * 1024 * 1024;
return fileData.size <= maxSizeBytes;
};
/**
* Format File Size
*
* Purpose: Convert bytes to human readable format
*
* @param bytes - File size in bytes
* @returns Formatted file size string
*/
export const formatFileSize = (bytes?: number): string => {
if (!bytes) return '';
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
if (bytes === 0) return '0 Bytes';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
};
/**
* Get File Type Display Name
*
* Purpose: Get user-friendly display name for file type
*
* @param mimeType - MIME type string
* @returns Display name for file type
*/
export const getFileTypeDisplay = (mimeType: string): string => {
const typeMap: Record<string, string> = {
'image/jpeg': 'JPEG',
'image/jpg': 'JPEG',
'image/png': 'PNG',
'image/gif': 'GIF',
'image/webp': 'WebP',
};
return typeMap[mimeType.toLowerCase()] || 'Image';
};
/*
* End of File: fileUpload.ts
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/