fix dropbox load fallback

This commit is contained in:
Christian Vidal Wolf
2026-05-20 13:59:35 +02:00
parent e8d05069f3
commit 396ff23d49
+72 -23
View File
@@ -1,6 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react'; import React, { useState, useMemo, useEffect } from 'react';
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { X } from 'lucide-react'; import { X } from 'lucide-react';
import defaultWorkbookUrl from '../data (3).xlsx?url';
import { cn } from './lib/utils'; import { cn } from './lib/utils';
import { AppState, ExcelRow, resolveColumnIndices, COLUMNS } from './types'; import { AppState, ExcelRow, resolveColumnIndices, COLUMNS } from './types';
import { ColumnsProvider } from './contexts/ColumnsContext'; import { ColumnsProvider } from './contexts/ColumnsContext';
@@ -85,6 +86,31 @@ function readStoredBcSyncQueue(): BcSyncQueue {
} }
} }
async function loadWorkbookFromUrl(url: string) {
const response = await fetch(url, { cache: 'no-store' });
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const arrayBuffer = await response.arrayBuffer();
if (arrayBuffer.byteLength < 100) {
throw new Error('File too small');
}
const wb = XLSX.read(arrayBuffer, { type: 'array' });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const allData = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
const rows = allData.slice(1);
const headers = allData.slice(0, 1)[0] || [];
return {
headers,
rows,
fileMeta: { rev: url, size: arrayBuffer.byteLength },
};
}
export default function App() { export default function App() {
const [session, setSession] = useState<AuthSession | null>(() => getStoredSession()); const [session, setSession] = useState<AuthSession | null>(() => getStoredSession());
@@ -201,22 +227,31 @@ export default function App() {
const cacheBuster = `t_${Date.now()}`; const cacheBuster = `t_${Date.now()}`;
const fileUrl = `/dropbox-file/scl/fi/usa8me7ywgylrij2bt6hj/Data-Matrix.xlsx?rlkey=tsec8csrhye54u1fdvk15ped1&dl=1&${cacheBuster}=${Date.now()}`; const fileUrl = `/dropbox-file/scl/fi/usa8me7ywgylrij2bt6hj/Data-Matrix.xlsx?rlkey=tsec8csrhye54u1fdvk15ped1&dl=1&${cacheBuster}=${Date.now()}`;
console.log('Fetching Data-Matrix.xlsx from Dropbox (hard refresh)...'); console.log('Fetching Data-Matrix.xlsx from Dropbox (hard refresh)...');
const response = await fetch(fileUrl, { cache: 'no-store' }); try {
if (!response.ok) throw new Error(`HTTP ${response.status}`); const response = await fetch(fileUrl, { cache: 'no-store' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const contentType = response.headers.get('content-type'); const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('text/html')) { if (contentType && contentType.includes('text/html')) {
throw new Error('Dropbox returned an HTML page instead of the Excel file. This usually means the sharing link has expired or requires manual interaction. Please generate a new "Copy Link" from Dropbox.'); throw new Error('Dropbox returned an HTML page instead of the Excel file.');
}
const arrayBuffer = await response.arrayBuffer();
if (arrayBuffer.byteLength < 100) throw new Error('File too small');
const wb = XLSX.read(arrayBuffer, { type: 'array' });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
allData = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
rows = allData.slice(1);
fileMeta = { rev: 'dev', size: arrayBuffer.byteLength };
} catch (devErr) {
console.warn('Dropbox dev load failed, using bundled workbook fallback:', devErr);
const fallback = await loadWorkbookFromUrl(defaultWorkbookUrl);
allData = [fallback.headers, ...fallback.rows];
rows = fallback.rows;
fileMeta = fallback.fileMeta;
} }
const arrayBuffer = await response.arrayBuffer();
if (arrayBuffer.byteLength < 100) throw new Error('File too small');
const wb = XLSX.read(arrayBuffer, { type: 'array' });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
allData = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
rows = allData.slice(1);
fileMeta = { rev: 'dev', size: arrayBuffer.byteLength };
} else { } else {
console.log('Fetching file info from Dropbox...'); console.log('Fetching file info from Dropbox...');
const infoRes = await fetch('/api/dropbox-proxy?info=1'); const infoRes = await fetch('/api/dropbox-proxy?info=1');
@@ -226,16 +261,30 @@ export default function App() {
} }
console.log('Fetching Data-Matrix.xlsx from proxy (hard refresh)...'); console.log('Fetching Data-Matrix.xlsx from proxy (hard refresh)...');
const response = await fetch('/api/dropbox-proxy', { cache: 'no-store' }); try {
if (!response.ok) throw new Error(`HTTP ${response.status}`); const response = await fetch('/api/dropbox-proxy', { cache: 'no-store' });
const arrayBuffer = await response.arrayBuffer(); if (!response.ok) throw new Error(`HTTP ${response.status}`);
if (arrayBuffer.byteLength < 100) throw new Error('File too small');
const wb = XLSX.read(arrayBuffer, { type: 'array' }); const contentType = response.headers.get('content-type');
const wsname = wb.SheetNames[0]; if (contentType && contentType.includes('text/html')) {
const ws = wb.Sheets[wsname]; throw new Error('Dropbox returned an HTML page instead of the Excel file.');
allData = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 }); }
rows = allData.slice(1);
const arrayBuffer = await response.arrayBuffer();
if (arrayBuffer.byteLength < 100) throw new Error('File too small');
const wb = XLSX.read(arrayBuffer, { type: 'array' });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
allData = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1 });
rows = allData.slice(1);
} catch (prodErr) {
console.warn('Dropbox prod load failed, using bundled workbook fallback:', prodErr);
const fallback = await loadWorkbookFromUrl(defaultWorkbookUrl);
allData = [fallback.headers, ...fallback.rows];
rows = fallback.rows;
fileMeta = fallback.fileMeta;
}
} }
if (rows.length > 0) { if (rows.length > 0) {