feat: Add UK inventory sync from Dropbox

- Create new API endpoint api/fetch-uk-inventory.ts
- Add processUKInventoryExcel function in dataProcessor.ts
- Update handleVendorStockFetch to load PANEU + UK in parallel
- Configure Vite proxy for UK inventory endpoint
- UK stock correctly populates 'uk' field in vendorStockMap
This commit is contained in:
Christian Vidal Wolf
2026-02-02 09:24:49 +01:00
parent ab9ac4f47e
commit e1e6f127be
4 changed files with 159 additions and 9 deletions
+31 -9
View File
@@ -5,7 +5,7 @@ import Dashboard from './components/Dashboard';
import FilterBar from './components/FilterBar';
import AIChat from './components/AIChat';
import CrazeLogo from './components/CrazeLogo';
import { processCSV, processExcel, filterData, aggregateData, processAdsCSV, processAdsExcel, mergeSalesAndAdsData, processTrafficExcel, processStockExcel, filterAdsData, calculateForecastViewData, processVendorStockExcel, calculateVelocityMap, getUniqueValues, processForecastExcel, processBuyBoxExcel } from './services/dataProcessor';
import { processCSV, processExcel, filterData, aggregateData, processAdsCSV, processAdsExcel, mergeSalesAndAdsData, processTrafficExcel, processStockExcel, filterAdsData, calculateForecastViewData, processVendorStockExcel, processUKInventoryExcel, calculateVelocityMap, getUniqueValues, processForecastExcel, processBuyBoxExcel } from './services/dataProcessor';
import { SalesRecord, FilterState, AggregatedData, AdsRecord, TrafficRecord, ForecastRecord, ProductForecastData } from './types';
import { queryGemini } from './services/geminiService';
import { ChartIcon, TableIcon, UploadIcon, DownloadIcon, CloseIcon, TrendingIcon, MegaphoneIcon } from './components/Icons';
@@ -185,16 +185,38 @@ const App: React.FC = () => {
const handleVendorStockFetch = useCallback(async () => {
try {
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}`);
console.log('[App] Fetching vendor stock (PANEU + UK) from Dropbox...');
const buffer = await response.arrayBuffer();
const data = await processVendorStockExcel(buffer);
setVendorStockMap(data);
console.log('[App] Successfully loaded PANEU vendor stock for', data.size, 'ASINs');
// Fetch both PANEU and UK inventory in parallel
const [paneuResponse, ukResponse] = await Promise.all([
fetch('/api/fetch-paneu-stock'),
fetch('/api/fetch-uk-inventory')
]);
let combinedMap = new Map<string, { eu: number; uk: number }>();
// Process PANEU stock (EU countries)
if (paneuResponse.ok) {
const paneuBuffer = await paneuResponse.arrayBuffer();
combinedMap = await processVendorStockExcel(paneuBuffer);
console.log('[App] PANEU stock loaded:', combinedMap.size, 'ASINs');
} else {
console.warn('[App] PANEU fetch failed:', paneuResponse.status);
}
// Process UK inventory and merge with existing map
if (ukResponse.ok) {
const ukBuffer = await ukResponse.arrayBuffer();
combinedMap = await processUKInventoryExcel(ukBuffer, combinedMap);
console.log('[App] UK inventory merged. Total ASINs:', combinedMap.size);
} else {
console.warn('[App] UK inventory fetch failed:', ukResponse.status);
}
setVendorStockMap(combinedMap);
console.log('[App] Successfully loaded combined vendor stock for', combinedMap.size, 'ASINs');
} catch (error) {
console.error("Failed to fetch/parse PANEU Vendor Stock", error);
console.error("Failed to fetch/parse Vendor Stock", error);
}
}, []);