Spaces:
Sleeping
Sleeping
| import axios from "axios"; | |
| import apiClient from '@/lib/api/axios-instance'; | |
| import { createHeaders } from '@/lib/api'; | |
| import { API_BASE_URL } from "@/config"; | |
| // Create API_URL from API_BASE_URL | |
| const API_URL = `${API_BASE_URL}/api`; | |
| export interface Attachment { | |
| attachmentId: number; | |
| fileName: string; | |
| fileType: string; | |
| filePath: string; | |
| entityType: string; | |
| entityId: number; | |
| description?: string; | |
| createdAt?: string; | |
| createdBy?: string; | |
| } | |
| export interface AttachmentCreateRequest { | |
| attachmentId: number; | |
| fileName: string; | |
| fileType: string; | |
| filePath: string; | |
| entityType: string; | |
| entityId: number; | |
| description?: string; | |
| _IFormFile: File; | |
| } | |
| export interface DownloadResult { | |
| blob: Blob; | |
| fileName: string; | |
| contentType: string; | |
| } | |
| export interface DownloadProgressCallback { | |
| (progress: number, totalSize: number): void; | |
| } | |
| export const attachmentApi = { | |
| getAll: async (): Promise<Attachment[]> => { | |
| try { | |
| const response = await apiClient.get(`${API_URL}/Attachments`); | |
| return response.data; | |
| } catch (error) { | |
| console.error("Error fetching all attachments:", error); | |
| throw error; | |
| } | |
| }, | |
| getById: async (id: number): Promise<Attachment> => { | |
| try { | |
| const response = await apiClient.get(`${API_URL}/Attachments/${id}`); | |
| return response.data; | |
| } catch (error) { | |
| console.error(`Error fetching attachment with ID ${id}:`, error); | |
| throw error; | |
| } | |
| }, | |
| getByEntityTypeAndId: async (entityType: string, entityId: number): Promise<Attachment[]> => { | |
| try { | |
| const response = await apiClient.get(`${API_URL}/Attachments/${entityType}/${entityId}`); | |
| return response.data; | |
| } catch (error) { | |
| console.error(`Error fetching attachments for ${entityType} with ID ${entityId}:`, error); | |
| throw error; | |
| } | |
| }, | |
| delete: async (id: number): Promise<boolean> => { | |
| try { | |
| const response = await apiClient.delete(`${API_URL}/Attachments/${id}`); | |
| return response.status === 200; | |
| } catch (error) { | |
| console.error(`Error deleting attachment with ID ${id}:`, error); | |
| throw error; | |
| } | |
| }, | |
| upload: async (data: FormData): Promise<Attachment> => { | |
| try { | |
| const response = await apiClient.post(`${API_URL}/Attachments/uploadfile`, data, { | |
| headers: { | |
| 'Content-Type': undefined, | |
| }, | |
| }); | |
| return response.data; | |
| } catch (error) { | |
| console.error("Error uploading attachment:", error); | |
| throw error; | |
| } | |
| }, | |
| download: async (id: number, onProgress?: DownloadProgressCallback): Promise<DownloadResult> => { | |
| try { | |
| // First get the attachment info to determine the correct filename | |
| const attachmentInfo = await attachmentApi.getById(id); | |
| // Download the file with the blob response type | |
| const response = await apiClient.get(`${API_URL}/Attachments/download/${id}`, { | |
| responseType: 'blob', | |
| }); | |
| // Extract content type from headers or use default | |
| const contentType = response.headers['content-type'] || | |
| attachmentInfo.fileType || | |
| 'application/octet-stream'; | |
| // Extract filename from Content-Disposition header if available | |
| const contentDisposition = response.headers['content-disposition'] || ''; | |
| let fileName = attachmentInfo.fileName; | |
| // Try to extract filename from Content-Disposition header | |
| const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); | |
| if (filenameMatch && filenameMatch[1]) { | |
| const extractedName = filenameMatch[1].replace(/['"]/g, ''); | |
| if (extractedName) { | |
| fileName = extractedName; | |
| } | |
| } | |
| console.log(`Downloaded file: ${fileName}, content-type: ${contentType}, size: ${response.data.size} bytes`); | |
| return { | |
| blob: response.data, | |
| fileName, | |
| contentType | |
| }; | |
| } catch (error) { | |
| console.error(`Error downloading attachment with ID ${id}:`, error); | |
| throw error; | |
| } | |
| }, | |
| // Method to directly trigger a file download | |
| downloadAndSave: async (id: number, onProgress?: DownloadProgressCallback): Promise<void> => { | |
| try { | |
| const result = await attachmentApi.download(id, onProgress); | |
| // Create a URL for the blob | |
| const url = window.URL.createObjectURL(result.blob); | |
| // Create a download link | |
| const link = document.createElement('a'); | |
| link.href = url; | |
| link.download = result.fileName; | |
| // Add to document, click and remove | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| // Release the object URL | |
| window.URL.revokeObjectURL(url); | |
| console.log(`File "${result.fileName}" downloaded successfully`); | |
| } catch (error) { | |
| console.error(`Error downloading and saving attachment with ID ${id}:`, error); | |
| throw error; | |
| } | |
| }, | |
| // Method to get a temporary view URL for an attachment | |
| getViewUrl: async (id: number): Promise<string> => { | |
| try { | |
| // Get attachment info to check file type | |
| const attachment = await attachmentApi.getById(id); | |
| const fileType = attachment.fileType.toLowerCase(); | |
| // Check if it's a viewable file type | |
| const isViewableType = | |
| fileType.includes('image') || | |
| fileType.includes('pdf') || | |
| fileType.includes('text') || | |
| fileType.includes('html') || | |
| fileType.includes('.jpg') || | |
| fileType.includes('.jpeg') || | |
| fileType.includes('.png') || | |
| fileType.includes('.gif') || | |
| fileType.includes('.webp') || | |
| fileType.includes('.pdf') || | |
| fileType.includes('.txt') || | |
| fileType.includes('.html'); | |
| if (!isViewableType) { | |
| throw new Error(`File type ${fileType} is not supported for preview`); | |
| } | |
| // Download the file as a blob and create a URL | |
| const result = await attachmentApi.download(id); | |
| const url = window.URL.createObjectURL(result.blob); | |
| return url; | |
| } catch (error) { | |
| console.error(`Error creating view URL for attachment with ID ${id}:`, error); | |
| throw error; | |
| } | |
| }, | |
| // Check if file is viewable | |
| isViewable: (attachment: Attachment): boolean => { | |
| const fileType = attachment.fileType.toLowerCase(); | |
| const fileName = attachment.fileName.toLowerCase(); | |
| // Check if it's a viewable file type | |
| return ( | |
| fileType.includes('image') || | |
| fileType.includes('pdf') || | |
| fileType.includes('text') || | |
| fileType.includes('html') || | |
| fileName.endsWith('.jpg') || | |
| fileName.endsWith('.jpeg') || | |
| fileName.endsWith('.png') || | |
| fileName.endsWith('.gif') || | |
| fileName.endsWith('.webp') || | |
| fileName.endsWith('.pdf') || | |
| fileName.endsWith('.txt') || | |
| fileName.endsWith('.html') | |
| ); | |
| } | |
| }; |