From 7e58e8aba4a9c7bf83dac74838d96a138019e558 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Mon, 2 Feb 2026 09:13:05 +0100 Subject: [PATCH] feat: Sync PANEU inventory from Dropbox - Add new API endpoint for PANEU stock from Dropbox - Update handleVendorStockFetch to use new endpoint - Configure Vite proxy for local development --- App.tsx | 10 +++++----- api/fetch-paneu-stock.ts | 39 +++++++++++++++++++++++++++++++++++++++ vite.config.ts | 6 ++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 api/fetch-paneu-stock.ts diff --git a/App.tsx b/App.tsx index 97821bd..cedf8d7 100644 --- a/App.tsx +++ b/App.tsx @@ -185,16 +185,16 @@ const App: React.FC = () => { const handleVendorStockFetch = useCallback(async () => { try { - console.log('[App] Fetching vendor stock from /Vendor Stock.xlsx...'); - const response = await fetch('/Vendor Stock.xlsx'); - if (!response.ok) throw new Error(`Failed to fetch vendor stock: ${response.status}`); + console.log('[App] Fetching PANEU vendor stock from /api/fetch-paneu-stock...'); + const response = await fetch('/api/fetch-paneu-stock'); + if (!response.ok) throw new Error(`Failed to fetch PANEU vendor stock: ${response.status}`); const buffer = await response.arrayBuffer(); const data = await processVendorStockExcel(buffer); setVendorStockMap(data); - console.log('[App] Successfully loaded vendor stock for', data.size, 'ASINs'); + console.log('[App] Successfully loaded PANEU vendor stock for', data.size, 'ASINs'); } catch (error) { - console.error("Failed to fetch/parse Vendor Stock", error); + console.error("Failed to fetch/parse PANEU Vendor Stock", error); } }, []); diff --git a/api/fetch-paneu-stock.ts b/api/fetch-paneu-stock.ts new file mode 100644 index 0000000..14f745f --- /dev/null +++ b/api/fetch-paneu-stock.ts @@ -0,0 +1,39 @@ +import type { VercelRequest, VercelResponse } from '@vercel/node'; + +// PANEU Stock from Dropbox (using dl=1 for direct download) +const PANEU_STOCK_DROPBOX_URL = "https://www.dropbox.com/scl/fi/xvsqi89mc8wk2i3jpndll/PANEU-Stock.xlsx?rlkey=djtbez2yi1sohjn203xnbjzl1&st=aogcoiw6&dl=1"; + +export default async function handler(req: VercelRequest, res: VercelResponse) { + // CORS headers + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + return res.status(200).end(); + } + + try { + console.log('[fetch-paneu-stock] Fetching PANEU Stock from Dropbox...'); + const response = await fetch(PANEU_STOCK_DROPBOX_URL, { + cache: 'no-store', + headers: { + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache' + } + }); + + if (!response.ok) { + throw new Error(`Dropbox responded with ${response.status}`); + } + + const buffer = await response.arrayBuffer(); + console.log('[fetch-paneu-stock] Successfully fetched PANEU Stock Excel, size:', buffer.byteLength); + + res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + res.status(200).send(Buffer.from(buffer)); + } catch (error: any) { + console.error('[fetch-paneu-stock] Error:', error); + res.status(500).json({ error: error.message }); + } +} diff --git a/vite.config.ts b/vite.config.ts index 36f8ac4..1d46ded 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -14,6 +14,12 @@ export default defineConfig(({ mode }) => { changeOrigin: true, rewrite: () => '', // Replace entire path with empty string (target has full URL) followRedirects: true + }, + '/api/fetch-paneu-stock': { + target: 'https://www.dropbox.com/scl/fi/xvsqi89mc8wk2i3jpndll/PANEU-Stock.xlsx?rlkey=djtbez2yi1sohjn203xnbjzl1&st=aogcoiw6&dl=1', + changeOrigin: true, + rewrite: () => '', + followRedirects: true } } },