diff --git a/index.html b/index.html
index 28ee219..e716782 100644
--- a/index.html
+++ b/index.html
@@ -458,12 +458,29 @@ function esc(s) {
// ═══════════════════════════════════════════════════════════
// ─── Photo ─────────────────────────────────────────────
// ═══════════════════════════════════════════════════════════
-function handlePhotoUpload(flagId, file) {
+function compressImage(file, maxW = 400, quality = 0.5) {
+ return new Promise((resolve) => {
+ const img = new Image();
+ const url = URL.createObjectURL(file);
+ img.onload = () => {
+ URL.revokeObjectURL(url);
+ let w = img.width, h = img.height;
+ if (w > maxW) { h = h * maxW / w; w = maxW; }
+ const c = document.createElement('canvas');
+ c.width = w; c.height = h;
+ const ctx = c.getContext('2d');
+ ctx.drawImage(img, 0, 0, w, h);
+ resolve(c.toDataURL('image/jpeg', quality));
+ };
+ img.src = url;
+ });
+}
+
+async function handlePhotoUpload(flagId, file) {
const flag = flags.find(f => f.id === flagId);
if (!flag || !file) return;
- const reader = new FileReader();
- reader.onload = (e) => { flag.photoData = e.target.result; renderList(); };
- reader.readAsDataURL(file);
+ flag.photoData = await compressImage(file);
+ renderList();
}
function removePhoto(flagId) {
@@ -692,10 +709,16 @@ document.getElementById('export-btn').addEventListener('click', () => {
Photo: f.photoData ?? '',
}));
const wb = XLSX.utils.book_new();
- const ws = XLSX.utils.json_to_sheet(rows);
+ const ws = XLSX.utils.json_to_sheet(rows, { cellDates: true });
ws['!cols'] = [{ wch: 12 }, { wch: 20 }, { wch: 10 }, { wch: 12 }, { wch: 12 }, { wch: 60 }, { wch: 30 }];
XLSX.utils.book_append_sheet(wb, ws, 'Flags');
- XLSX.writeFile(wb, 'flag_export.xlsx');
+ try {
+ XLSX.writeFile(wb, 'flag_export.xlsx');
+ } catch (e) {
+ if (e.message?.includes('32767')) {
+ alert('Photo data is too large. Try uploading smaller photos.');
+ } else { throw e; }
+ }
});
// ═══════════════════════════════════════════════════════════