import type { UploadedFileDto } from '~~/.api-client' import { useFileApi } from './useFileApi' import { useLogger } from '../useLogger' export interface UploadedFileMetadata { fileId: string filename: string size: number mimeType: string uploadedAt: string } export function useFile() { const fileApi = useFileApi() const logger = useLogger().withTag('file') const { t } = useI18n() async function uploadFile(params: { file: File applicationFormId?: string formElementReference: string organizationId?: string }): Promise { try { logger.debug('Uploading file:', params.file.name) return await fileApi.uploadFile(params) } catch (e: unknown) { logger.error('Failed uploading file:', e) // Enhanced error handling with user-friendly messages if (e && typeof e === 'object' && 'status' in e) { const error = e as { status: number } if (error.status === 413) { return Promise.reject( new Error( t('applicationForms.formElements.fileUpload.fileTooLarge', { filename: params.file.name, maxSize: '10MB' }) ) ) } else if (error.status === 415) { return Promise.reject(new Error(t('applicationForms.formElements.fileUpload.unsupportedType'))) } } return Promise.reject(new Error(t('applicationForms.formElements.fileUpload.uploadFailed'))) } } async function downloadFile(id: string, filename: string): Promise { try { logger.debug('Downloading file:', id) const blob = await fileApi.downloadFileContent(id) // Create download link const url = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = filename document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(url) } catch (e: unknown) { logger.error('Failed downloading file:', e) return Promise.reject(new Error(t('applicationForms.formElements.fileUpload.downloadFailed'))) } } function isViewableInBrowser(mimeType: string): boolean { return mimeType === 'application/pdf' || mimeType.startsWith('image/') } function viewFile(id: string): void { const url = fileApi.getFileViewUrl(id) window.open(url, '_blank') } async function deleteFile(id: string): Promise { try { logger.debug('Deleting file:', id) return await fileApi.deleteFile(id) } catch (e: unknown) { logger.error('Failed deleting file:', e) return Promise.reject(new Error(t('applicationForms.formElements.fileUpload.deleteFailed'))) } } async function associateFilesWithApplicationForm(applicationFormId: string, fileIds: string[]): Promise { try { logger.debug('Associating files with application form:', { applicationFormId, fileIds }) return await fileApi.associateFilesWithApplicationForm(applicationFormId, fileIds) } catch (e: unknown) { logger.error('Failed associating files with application form:', e) return Promise.reject(e) } } function parseUploadedFiles(formOptionsValues: string[]): UploadedFileMetadata[] { return formOptionsValues .map((value) => { try { return JSON.parse(value) as UploadedFileMetadata } catch { return null } }) .filter((file): file is UploadedFileMetadata => file !== null) } function createFileMetadata(response: UploadedFileDto): UploadedFileMetadata { return { fileId: response.id, filename: response.originalFilename, size: response.size, mimeType: response.mimeType, uploadedAt: response.uploadedAt.toISOString() } } function getFileIcon(mimeType: string): string { if (mimeType.startsWith('image/')) return 'i-ph-image' if (mimeType === 'application/pdf') return 'i-ph-file-pdf' if (mimeType.includes('word')) return 'i-ph-file-doc' if (mimeType.includes('zip')) return 'i-ph-file-zip' return 'i-ph-file' } function formatFileSize(bytes: number): string { if (bytes === 0) return '0 B' const k = 1024 const sizes = ['B', 'KB', 'MB', 'GB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}` } return { uploadFile, downloadFile, viewFile, deleteFile, associateFilesWithApplicationForm, parseUploadedFiles, createFileMetadata, getFileIcon, formatFileSize, isViewableInBrowser } }