From 812425a1ef243b9bdc1424dc552dd0ad96480a28 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Fri, 20 Feb 2026 11:07:34 +0100 Subject: [PATCH] feat: add marketplace differentiation to Experiment Tracker Each experiment now tracks which marketplace (Amazon DE, UK, etc.) it applies to. The form defaults to the currently active marketplace filter, and the delta % calculation filters by both product line and marketplace. Co-Authored-By: Claude Opus 4.6 --- components/ExperimentTracker.tsx | 50 ++++++++++++++++++++++++++++---- components/WeeklyGrid.tsx | 2 +- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/components/ExperimentTracker.tsx b/components/ExperimentTracker.tsx index 42ade8a..9ca083d 100644 --- a/components/ExperimentTracker.tsx +++ b/components/ExperimentTracker.tsx @@ -11,6 +11,7 @@ export interface Experiment { id: string; week: string; // "2026-08" matching YYYY-WW format used in pivot data product_line: string; + marketplace: string; // e.g. "Amazon DE", "Amazon UK" action_type: 'SEO' | 'Price' | 'Advertising' | 'Images' | 'A+ Content' | 'Variants' | 'Stock' | 'Other'; description: string; expected_impact: 'More Sales' | 'Better Visibility' | 'Lower Costs'; @@ -93,6 +94,7 @@ interface ExperimentTrackerProps { rows: WeeklyPivotRow[]; weeks: string[]; // sorted descending (most recent first) primaryMetric: 'units' | 'revenue'; + customerFilters: string[]; // active marketplace filters from parent } // --- Custom dot for experiment markers --- @@ -150,6 +152,7 @@ const ChartTooltipContent: React.FC = ({ active, payload, label, experiment {exp.action_type} {exp.product_line} + {exp.marketplace && ({exp.marketplace})}

{exp.description}

@@ -162,7 +165,7 @@ const ChartTooltipContent: React.FC = ({ active, payload, label, experiment // --- Main Component --- -const ExperimentTracker: React.FC = ({ rows, weeks, primaryMetric }) => { +const ExperimentTracker: React.FC = ({ rows, weeks, primaryMetric, customerFilters }) => { const [experiments, setExperiments] = useState(loadExperiments); const [showForm, setShowForm] = useState(false); const [showPanel, setShowPanel] = useState(true); @@ -171,10 +174,24 @@ const ExperimentTracker: React.FC = ({ rows, weeks, prim // Form state const [formWeek, setFormWeek] = useState(getCurrentWeek); const [formLine, setFormLine] = useState(''); + const [formMarketplace, setFormMarketplace] = useState(''); const [formAction, setFormAction] = useState('SEO'); const [formDesc, setFormDesc] = useState(''); const [formImpact, setFormImpact] = useState('More Sales'); + // Available marketplaces from data + const marketplaces = useMemo(() => { + const mks = new Set(rows.map(r => r.customer).filter(Boolean)); + return Array.from(mks).sort(); + }, [rows]); + + // Default marketplace to active filter when opening form + const defaultMarketplace = useMemo(() => { + if (customerFilters.length === 1) return customerFilters[0]; + if (customerFilters.length > 0) return customerFilters[0]; + return marketplaces[0] || ''; + }, [customerFilters, marketplaces]); + // Available product lines from data const productLines = useMemo(() => { const lines = new Set(rows.map(r => r.line).filter(Boolean)); @@ -218,6 +235,7 @@ const ExperimentTracker: React.FC = ({ rows, weeks, prim let total = 0; for (const row of rows) { if (row.line !== exp.product_line) continue; + if (exp.marketplace && row.customer !== exp.marketplace) continue; total += primaryMetric === 'units' ? (row.unitsByWeek[w] || 0) : (row.revenueByWeek[w] || 0); @@ -252,12 +270,13 @@ const ExperimentTracker: React.FC = ({ rows, weeks, prim }, []); const handleSubmit = useCallback(() => { - if (!formLine || !formDesc.trim()) return; + if (!formLine || !formMarketplace || !formDesc.trim()) return; const newExp: Experiment = { id: `exp_${Date.now()}`, week: formWeek, product_line: formLine, + marketplace: formMarketplace, action_type: formAction, description: formDesc.trim(), expected_impact: formImpact, @@ -269,7 +288,7 @@ const ExperimentTracker: React.FC = ({ rows, weeks, prim setShowForm(false); setFormDesc(''); setFormWeek(getCurrentWeek()); - }, [formWeek, formLine, formAction, formDesc, formImpact, experiments, updateExperiments]); + }, [formWeek, formLine, formMarketplace, formAction, formDesc, formImpact, experiments, updateExperiments]); const handleStatusChange = useCallback((id: string, newStatus: ExperimentStatus) => { updateExperiments(experiments.map(e => e.id === id ? { ...e, status: newStatus } : e)); @@ -299,7 +318,7 @@ const ExperimentTracker: React.FC = ({ rows, weeks, prim