feat: replace Vendor tab with BSR tracker

This commit is contained in:
Christian Vidal Wolf
2026-03-02 15:22:12 +01:00
parent 918da227ee
commit 243c44c7f7
7 changed files with 278 additions and 251 deletions
+20 -3
View File
@@ -5,8 +5,8 @@ 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, processUKInventoryExcel, calculateVelocityMap, getUniqueValues, processForecastExcel, processBuyBoxExcel, processVendorCSV } from './services/dataProcessor';
import { SalesRecord, FilterState, AggregatedData, AdsRecord, TrafficRecord, ForecastRecord, ProductForecastData, ActiveExperiment } from './types';
import { processCSV, processExcel, filterData, aggregateData, processAdsCSV, processAdsExcel, mergeSalesAndAdsData, processTrafficExcel, processStockExcel, filterAdsData, calculateForecastViewData, processVendorStockExcel, processUKInventoryExcel, calculateVelocityMap, getUniqueValues, processForecastExcel, processBuyBoxExcel, processVendorCSV, processBSRExcel } from './services/dataProcessor';
import { SalesRecord, FilterState, AggregatedData, AdsRecord, TrafficRecord, ForecastRecord, ProductForecastData, ActiveExperiment, BSRRecord } from './types';
import { queryGemini } from './services/geminiService';
import { ChartIcon, TableIcon, UploadIcon, DownloadIcon, CloseIcon, TrendingIcon, MegaphoneIcon } from './components/Icons';
import { loadSalesData, saveSalesData, clearSalesData, loadAdsData, saveAdsData, clearAdsData } from './services/storage';
@@ -60,6 +60,7 @@ const App: React.FC = () => {
const [cachedForecastRecords, setCachedForecastRecords] = useState<ForecastRecord[]>([]);
const [lastForecastFile, setLastForecastFile] = useState<string | null>(null);
const [buyBoxLostMap, setBuyBoxLostMap] = useState<Map<string, { countries: string[]; reasons: Record<string, string> }>>(new Map());
const [bsrData, setBsrData] = useState<BSRRecord[]>([]);
// Experiments state
const [experimentMap, setExperimentMap] = useState<Map<string, ActiveExperiment[]>>(new Map());
@@ -248,6 +249,21 @@ const App: React.FC = () => {
}
}, []);
const handleBSRFetch = useCallback(async () => {
try {
console.log('[App] Fetching BSR data from /api/fetch-bsr...');
const response = await fetch('/api/fetch-bsr');
if (!response.ok) throw new Error(`Failed to fetch BSR data: ${response.status}`);
const buffer = await response.arrayBuffer();
const data = await processBSRExcel(buffer);
setBsrData(data);
console.log('[App] Successfully loaded BSR data:', data.length, 'records');
} catch (error) {
console.error("Failed to fetch/parse BSR data", error);
}
}, []);
const handleExperimentsFetch = useCallback(async () => {
try {
const expMap = await getActiveExperiments(rawData);
@@ -400,7 +416,8 @@ const App: React.FC = () => {
handleStockFetch(),
handleVendorStockFetch(),
handleBuyBoxFetch(),
handleExperimentsFetch()
handleExperimentsFetch(),
handleBSRFetch()
]).catch(e => console.warn("Background fetch failed", e));
// 1f. Fetch Forecast data