import { ref } from 'vue'; import axios from 'axios'; /** * Composable for handling file uploads. * * @param {Object} options * @param {string[]} options.acceptedTypes - Array of accepted MIME types (default: ['image/*']) * @param {number} options.maxSizeMB - Maximum file size in MB (default: 10) * @param {string} options.category - Category for the upload (default: 'general') */ export function useFileUpload(options = {}) { const acceptedTypes = options.acceptedTypes || ['image/jpeg', 'image/png', 'image/webp', 'image/gif']; const maxSizeMB = options.maxSizeMB || 10; const category = options.category || 'general'; const photoHashes = ref([]); const isUploading = ref(false); const uploadError = ref(null); /** * Upload a file to the server. * * @param {File} file * @returns {Promise} */ const uploadFile = async (file) => { // Validation if (file.size > maxSizeMB * 1024 * 1024) { uploadError.value = `File size exceeds ${maxSizeMB}MB limit.`; return null; } const isAccepted = acceptedTypes.some(type => { if (type.endsWith('/*')) { const baseType = type.split('/')[0]; return file.type.startsWith(`${baseType}/`); } return file.type === type; }); if (!isAccepted && acceptedTypes.length > 0) { uploadError.value = 'Invalid file type.'; return null; } isUploading.value = true; uploadError.value = null; const formData = new FormData(); formData.append('file', file); try { const response = await axios.post(`/File/Upload/${category}`, formData, { headers: { 'Content-Type': 'multipart/form-data' } }); if (response.data && response.data.success && response.data.hashkey) { const hashkey = response.data.hashkey; photoHashes.value.push(hashkey); return response.data; } else { throw new Error(response.data?.message || 'Upload failed'); } } catch (err) { console.error('Upload error:', err); const status = err.response?.status; const backendMsg = err.response?.data?.message || err.response?.data?.error; if (status === 403) { uploadError.value = "You don't have permission to upload files here."; } else if (status === 413) { uploadError.value = 'File too large.'; } else { uploadError.value = backendMsg || err.message || 'Failed to upload file.'; } return null; } finally { isUploading.value = false; } }; /** * Remove a hash from the list. * * @param {string} hash */ const removeHash = (hash) => { photoHashes.value = photoHashes.value.filter(h => h !== hash); }; /** * Set initial hashes (e.g., when loading existing data). * * @param {string[]} hashes */ const setInitialHashes = (hashes) => { if (Array.isArray(hashes)) { photoHashes.value = [...hashes]; } }; return { photoHashes, isUploading, uploadError, uploadFile, removeHash, setInitialHashes }; }