diff --git a/App.tsx b/App.tsx index db6aa62..adc3623 100644 --- a/App.tsx +++ b/App.tsx @@ -119,6 +119,25 @@ const App: React.FC = () => { } }, []); + const handleTrafficFetch = useCallback(async () => { + try { + console.log('[App] Fetching traffic from /api/fetch-traffic...'); + const response = await fetch('/api/fetch-traffic'); + + if (!response.ok) { + throw new Error(`Failed to fetch Traffic: ${response.status} ${response.statusText}`); + } + + const buffer = await response.arrayBuffer(); + const data = await processTrafficExcel(buffer); + + setTrafficData(data); + console.log('[App] Successfully loaded', data.length, 'traffic records'); + } catch (error) { + console.error("Failed to fetch/parse Traffic", error); + } + }, []); + const initializeData = (data: SalesRecord[]) => { setRawData(data); setFilters({ @@ -188,6 +207,10 @@ const App: React.FC = () => { console.log("Fetching fresh Ads from URL..."); handleAdsFetch(); } + + // 1c. Always fetch Traffic data (no caching for now) + console.log("Fetching Traffic data..."); + handleTrafficFetch(); }; initApp(); }, [handleDataFetch]); diff --git a/api/fetch-traffic.ts b/api/fetch-traffic.ts new file mode 100644 index 0000000..4255004 --- /dev/null +++ b/api/fetch-traffic.ts @@ -0,0 +1,32 @@ +import type { VercelRequest, VercelResponse } from '@vercel/node'; + +const TRAFFIC_DROPBOX_URL = "https://www.dropbox.com/scl/fi/9cenju8djxav9z6q5if6m/Traffic-Weekly.xlsx?rlkey=r2oaixmnvzq6nnjuus0uowa6l&st=r7knws3r&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-traffic] Fetching Traffic from Dropbox...'); + const response = await fetch(TRAFFIC_DROPBOX_URL); + + if (!response.ok) { + throw new Error(`Dropbox responded with ${response.status}`); + } + + const buffer = await response.arrayBuffer(); + console.log('[fetch-traffic] Successfully fetched Traffic 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-traffic] Error:', error); + res.status(500).json({ error: error.message }); + } +}