Shows previous week and same week prior year values (Units, Revenue, Ads Spend, GV) with % change indicators when hovering any week cell in the TOTALS row.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Added stockMap, vendorStockMap, buyBoxLostMap, top50Mode to Dashboard props destructuring
- This fixes 'stockMap is not defined' error in TopMovers
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Add || null to years array access to prevent undefined values
- Add !currentYear || !previousYear to insufficient data check
- This prevents errors when filtered data has less than 2 years
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Removed debug console.log that was accessing data before null check
- Fixed colSpan in TopMovers empty state message (7 -> 10 columns)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
- Added StockBadge, VendorStockBadge and BuyBoxWarningBadge to TopMovers component
- Updated Dashboard to pass stockMap, vendorStockMap, buyBoxLostMap and top50Mode props
- Updated App.tsx to pass the required maps to Dashboard
- Table now shows 3 new columns: Stock (GMBH), Vendor (Amazon Warehouse), and Buy Box status
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Changed rawData prop from rawData to ytdFilteredData so the Top Movers
component respects all active filters (customer, year, month, week,
product line, SKU, title, ASIN, stock)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Move useMemo before early return in WaterfallModal to comply with Rules of Hooks.
Wrap App with ErrorBoundary so future render crashes show an error panel instead of a silent black screen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
filteredAdsData applies PAN_EU default when no marketplace is selected,
cutting UK/other spend and showing 118k instead of the full 151k.
mktAdsData skips the PAN_EU restriction: no customer filter = all
countries, still respects explicit customer/year/week selections.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed the `if (asin)` guard so records without a product ASIN
(e.g. campaign-level rows) accumulate in adsSpendMap and appear as
an 'Unassigned Ad Spend' row, ensuring the total PPC spend is the
same as in the ADs Weekly tab.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These Excel files only contain 2025 data. When the top filter excludes
2025 (e.g. year=2024), the maps are ignored so columns show 0 instead
of stale 2025 figures.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs fixed:
1. Removed hardcoded year===2025 filter (data is already pre-filtered)
2. ASINs with ad spend but no sales records were silently dropped —
now appended as extra rows so the total PPC spend matches ADs Weekly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MktDataView now receives filteredData/filteredAdsData so the global
FilterBar controls the tab's data. Removed the local "All Categories"
dropdown that previously sat next to the Include COGS toggle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace fetch-deals, fetch-promos, fetch-chargebacks with a single
/api/fetch-mkt-data?file=deals|promos|chargebacks endpoint.
Update MktDataView fetch calls accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all mock data in the Profitability Dashboard with live data:
- Add 3 new API routes (fetch-deals, fetch-promos, fetch-chargebacks) proxying Dropbox Excel files
- MktDataView now accepts rawData/adsData props and fetches+parses the 3 new files on mount
- SELL OUT and units aggregated globally across all marketplaces from rawData
- PPC Spend aggregated globally from adsData; ACoS calculated as spend/sales
- Deals (col A→C), Promos (col E→K), Chargebacks (col AN→B) parsed and summed per ASIN
- Category filter populated from product line metadata
- Loading skeleton shown while files are fetching
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BSRRecord.market is stored as short codes ('DE', 'IT', etc.) from the
Excel file, but the chart was comparing against full names ('Amazon DE',
'Amazon IT', etc.) — causing bsrRecordsForMarket to always be empty and
the BSR line to never render. Added normalizeBsrMarket() to map short
codes to full names before filtering. Also removed the debug strip.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use React's useDeferredValue to decouple UI responsiveness from
expensive data reprocessing. Checkboxes now update immediately on
click; filterData/filterAdsData/filterBsrData and all downstream
useMemos run as a low-priority background pass. Added local optimistic
state in MultiSelectDropdown as a belt-and-suspenders layer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>