Files
gremiumhub/legalconsenthub/app/composables/file/useFile.ts

151 lines
4.6 KiB
TypeScript

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<UploadedFileDto> {
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<void> {
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<void> {
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<void> {
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
}
}