diff --git a/frontend/index.html b/frontend/index.html
index a572ac0..09c3543 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -20,6 +20,7 @@
+
SIB - Sistema de Transporte
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 326ed49..fae051e 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -15,6 +15,7 @@
"@googlemaps/js-api-loader": "^2.0.2",
"@supabase/supabase-js": "^2.97.0",
"@tailwindcss/vite": "^4.2.0",
+ "browser-image-compression": "^2.0.2",
"chart.js": "^4.5.1",
"html2canvas": "^1.4.1",
"jspdf": "^4.1.0",
@@ -4016,6 +4017,15 @@
"node": "18 || 20 || >=22"
}
},
+ "node_modules/browser-image-compression": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/browser-image-compression/-/browser-image-compression-2.0.2.tgz",
+ "integrity": "sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw==",
+ "license": "MIT",
+ "dependencies": {
+ "uzip": "0.20201231.0"
+ }
+ },
"node_modules/browserslist": {
"version": "4.28.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
@@ -8230,6 +8240,12 @@
"base64-arraybuffer": "^1.0.2"
}
},
+ "node_modules/uzip": {
+ "version": "0.20201231.0",
+ "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz",
+ "integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==",
+ "license": "MIT"
+ },
"node_modules/vite": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index f5f2174..524fd2e 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -16,6 +16,7 @@
"@googlemaps/js-api-loader": "^2.0.2",
"@supabase/supabase-js": "^2.97.0",
"@tailwindcss/vite": "^4.2.0",
+ "browser-image-compression": "^2.0.2",
"chart.js": "^4.5.1",
"html2canvas": "^1.4.1",
"jspdf": "^4.1.0",
diff --git a/frontend/src/components/AppImage.vue b/frontend/src/components/AppImage.vue
new file mode 100644
index 0000000..4e1a4d8
--- /dev/null
+++ b/frontend/src/components/AppImage.vue
@@ -0,0 +1,88 @@
+
+
+
![]()
+
+
+
+
+
+
diff --git a/frontend/src/views/AdminBusinessEditor.vue b/frontend/src/views/AdminBusinessEditor.vue
index d30aac1..557498d 100644
--- a/frontend/src/views/AdminBusinessEditor.vue
+++ b/frontend/src/views/AdminBusinessEditor.vue
@@ -4,6 +4,22 @@ import { useRouter, useRoute } from 'vue-router';
import { businessService } from '@/services/businessService';
import type { Business } from '@/types';
import { useAuthStore } from '@/stores/auth';
+import imageCompression from 'browser-image-compression';
+
+async function compressImage(file: File) {
+ const options = {
+ maxSizeMB: 0.5,
+ maxWidthOrHeight: 1200,
+ useWebWorker: true,
+ fileType: 'image/webp'
+ };
+ try {
+ return await imageCompression(file, options);
+ } catch (err) {
+ console.error('Error compressing image', err);
+ return file; // fallback to original
+ }
+}
const router = useRouter();
const route = useRoute();
@@ -145,7 +161,8 @@ async function saveBusiness() {
if (galleryFiles.value.length > 0) {
const uploadedUrls: string[] = [];
for (const gFile of galleryFiles.value) {
- const url = await businessService.uploadImage(gFile);
+ const compressedFile = await compressImage(gFile) as File;
+ const url = await businessService.uploadImage(compressedFile);
uploadedUrls.push(url);
}
// Combinar las URL existentes ya serializadas + las nuevas subidas
@@ -154,7 +171,8 @@ async function saveBusiness() {
}
if (selectedFile.value) {
- formData.append('image', selectedFile.value);
+ const compressedMain = await compressImage(selectedFile.value) as File;
+ formData.append('image', compressedMain);
}
if (isEditing.value && businessForm.value.id) {
diff --git a/frontend/src/views/CouponsView.vue b/frontend/src/views/CouponsView.vue
index e53011d..7120e48 100644
--- a/frontend/src/views/CouponsView.vue
+++ b/frontend/src/views/CouponsView.vue
@@ -1,10 +1,10 @@
-