From 6bcf697165b5336abc634045e9da2e77c75e9181 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Thu, 23 Apr 2026 16:12:09 +0200 Subject: [PATCH] fix: always use fresh Dropbox Excel values on load --- src/App.tsx | 73 +++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d6d86f8..6c1bd3b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -158,65 +158,32 @@ export default function App() { } }); - const articleNoIdx = resolvedCols.ARTICLE_NO; +const articleNoIdx = resolvedCols.ARTICLE_NO; const processedRows = rows.map(row => { - const articleNo = String(row[articleNoIdx]); - const synced = syncedData[articleNo]; - - // Start with Dropbox values (default) - fresh from Excel + // Simply use Dropbox values - no merge logic + // Manual edits are preserved in Supabase and shown in Change History + // but fresh Excel data takes precedence on reload let finalRow = [...row]; - // Only preserve Supabase value if it's DIFFERENT from Dropbox (meaning someone edited it intentionally) - // This keeps the TYPE = "Surprise Bath bomb" edits while avoiding stale SRP/UVP values - if (synced) { - const oldData = synced.data; - const valAt12 = oldData[12]; - const needsShift = typeof valAt12 === 'number' || (typeof valAt12 === 'string' && /^[0-9.]+$/.test(valAt12)); - - editableColumns.forEach(idx => { - let mergeIdx = idx; - if (needsShift && idx >= 12) { - mergeIdx = idx - 1; - } - - const dbxValue = row[idx]; - const supabaseValue = oldData[mergeIdx]; - - // Only use Supabase value if it's different from Dropbox (edited intentionally) - if (supabaseValue !== undefined && supabaseValue !== null) { - // Compare as strings to handle numeric formatting differences - const dbxStr = String(dbxValue ?? ''); - const supabaseStr = String(supabaseValue); - - // Keep Supabase value only if it was actually edited (different from Excel) - if (dbxStr !== supabaseStr) { - finalRow[idx] = supabaseValue; - } - } - }); - setRowStatuses(prev => ({ ...prev, [articleNo]: synced.status || 'synced' })); - } - // Otherwise use Dropbox values (don't merge, just process formatting) - return finalRow.map((val: any, idx: number) => { if (val === undefined || val === null || val === '') return val; const header = (headers[idx] || '').toLowerCase(); - - if ((header.includes('id') || header.includes('no') || header.includes('code') || - header.includes('art.') || header.includes('barcode') || header.includes('article')) && - !(header.includes('nw') || header.includes('gw') || header.includes('weight') || header.includes('kg'))) { - return val; - } - - const formatKeywords = ['price', 'eur', 'cost', 'msrp', 'net', 'gross', 'netto', 'brutto', 'pp', 'pph', 'uvp', 'vpe', 'stk', 'nw', 'gw', 'weight', 'kg']; - const shouldFormat = formatKeywords.some(kw => header.includes(kw)); - - if (typeof val === 'number') { - return Number(val.toFixed(2)); - } - - if (typeof val === 'string') { - const normalized = val.trim().replace(',', '.'); + + if ((header.includes('id') || header.includes('no') || header.includes('code') || + header.includes('art.') || header.includes('barcode') || header.includes('article')) && + !(header.includes('nw') || header.includes('gw') || header.includes('weight') || header.includes('kg'))) { + return val; + } + + const formatKeywords = ['price', 'eur', 'cost', 'msrp', 'net', 'gross', 'netto', 'brutto', 'pp', 'pph', 'uvp', 'vpe', 'stk', 'nw', 'gw', 'weight', 'kg']; + const shouldFormat = formatKeywords.some(kw => header.includes(kw)); + + if (typeof val === 'number') { + return Number(val.toFixed(2)); + } + + if (typeof val === 'string') { + const normalized = val.trim().replace(',', '.'); const num = parseFloat(normalized); if (!isNaN(num) && (shouldFormat || val.includes('.') || val.includes(','))) { return num.toFixed(2);