feat: remove MKT and Experiments tabs and all related code

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Vidal Wolf
2026-06-12 08:29:47 +02:00
co-authored by Claude Sonnet 4.6
parent 9f9c0c2975
commit 76d901fcde
25 changed files with 11 additions and 4985 deletions
+3 -85
View File
@@ -6,14 +6,10 @@ 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, processBSRExcel, filterBsrData, isAllowedCustomer, isRealSale } from './services/dataProcessor';
import { SalesRecord, FilterState, AggregatedData, AdsRecord, TrafficRecord, ForecastRecord, ProductForecastData, ActiveExperiment, BSRRecord } from './types';
import { SalesRecord, FilterState, AggregatedData, AdsRecord, TrafficRecord, ForecastRecord, ProductForecastData, BSRRecord } from './types';
import { queryGemini } from './services/geminiService';
import { ChartIcon, TableIcon, CloseIcon, TrendingIcon, MegaphoneIcon } from './components/Icons';
import { loadSalesData, saveSalesData, clearSalesData, loadAdsData, saveAdsData, clearAdsData } from './services/storage';
import {
listExperiments,
getActiveExperiments,
} from './services/experiments';
// Lazy load heavy components for better initial performance
const DataGrid = lazy(() => import('./components/DataGrid'));
@@ -21,9 +17,6 @@ const WeeklyGrid = lazy(() => import('./components/WeeklyGrid'));
const AdsPerformance = lazy(() => import('./components/AdsPerformance'));
const ForecastView = lazy(() => import('./components/ForecastView'));
const VendorDataView = lazy(() => import('./components/VendorDataView'));
const ExperimentsView = lazy(() => import('./components/ExperimentsView'));
const MktDataView = lazy(() => import('./components/mkt/MktDataView'));
// Loading fallback component
const LoadingSpinner = () => (
@@ -51,7 +44,7 @@ const App: React.FC = () => {
const [trafficData, setTrafficData] = useState<TrafficRecord[]>([]);
const [loading, setLoading] = useState(true);
const [syncing, setSyncing] = useState(false);
const [view, setView] = useState<'dashboard' | 'table' | 'weekly' | 'ads' | 'forecast' | 'vendor' | 'experiments' | 'mkt'>('dashboard');
const [view, setView] = useState<'dashboard' | 'table' | 'weekly' | 'ads' | 'forecast' | 'vendor'>('dashboard');
const [forecastData, setForecastData] = useState<ProductForecastData[]>([]);
const [isChatOpen, setIsChatOpen] = useState(false);
const [activeUrl, setActiveUrl] = useState<string | null>(() => localStorage.getItem('craze_csv_url') || PERMANENT_DROPBOX_URL);
@@ -63,10 +56,6 @@ const App: React.FC = () => {
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());
// Experiment modal state removed — detail/create are now inline in ExperimentsView
// Modal State
const [isDataModalOpen, setIsDataModalOpen] = useState(false);
@@ -266,17 +255,6 @@ const App: React.FC = () => {
}
}, []);
const handleExperimentsFetch = useCallback(async () => {
try {
const expMap = await getActiveExperiments(rawData);
setExperimentMap(expMap);
console.log('[App] Loaded experiments for', expMap.size, 'ASINs');
} catch (error) {
console.error("Failed to fetch experiments", error);
}
}, [rawData]);
const handleForecastFetch = useCallback(async (sales: SalesRecord[], globalSales: SalesRecord[], activeFilters: FilterState) => {
try {
const isUK = activeFilters.customer.includes('Amazon UK');
@@ -356,11 +334,6 @@ const App: React.FC = () => {
setView('ads');
}, []);
// Create experiment for a specific line — now handled inline by ExperimentsView
const handleCreateExperimentForLine = useCallback((_line: string) => {
setView('experiments');
}, []);
// 1. Initial Load from Cache (IndexedDB) or Auto-Fetch Permanent URL
useEffect(() => {
const initApp = async () => {
@@ -418,7 +391,6 @@ const App: React.FC = () => {
handleStockFetch(),
handleVendorStockFetch(),
handleBuyBoxFetch(),
handleExperimentsFetch(),
handleBSRFetch()
]).catch(e => console.warn("Background fetch failed", e));
@@ -550,15 +522,6 @@ const App: React.FC = () => {
const filteredAdsData = useMemo(() => filterAdsData(adsData, deferredFilters, globalAsinMetadata, stockMap, vendorStockMap, top50Mode), [adsData, deferredFilters, globalAsinMetadata, stockMap, vendorStockMap, top50Mode]);
console.timeEnd('filteredAdsData');
const mktAdsData = useMemo(() => adsData.filter(ad => {
const countryMatch = deferredFilters.customer.length === 0
? true
: deferredFilters.customer.some(c => c.toUpperCase() === ad.country.toUpperCase());
const yearMatch = deferredFilters.year.length === 0 || deferredFilters.year.includes(ad.year.toString());
const weekMatch = deferredFilters.week.length === 0 || deferredFilters.week.includes(`W${ad.week}`);
return countryMatch && yearMatch && weekMatch;
}), [adsData, deferredFilters.customer, deferredFilters.year, deferredFilters.week]);
console.time('aggregatedData');
const aggregatedData = useMemo(() => aggregateData(filteredData), [filteredData]);
console.timeEnd('aggregatedData');
@@ -796,13 +759,6 @@ const App: React.FC = () => {
>
<TrendingIcon /> <span className="hidden lg:inline">Weekly Sales</span>
</button>
<button
onClick={() => setView('mkt')}
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
${view === 'mkt' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
>
<ChartIcon /> <span className="hidden lg:inline">MKT</span>
</button>
<button
onClick={() => setView('ads')}
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
@@ -824,14 +780,6 @@ const App: React.FC = () => {
>
<ChartIcon /> <span className="hidden lg:inline">BSR</span>
</button>
<button
onClick={() => setView('experiments')}
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-all
${view === 'experiments' ? 'bg-slate-800 text-white shadow-sm ring-1 ring-white/10' : 'text-slate-400 hover:text-white hover:bg-slate-800/50'}`}
>
<span className="text-lg">🧪</span> <span className="hidden lg:inline">Experiments</span>
</button>
</div>
</div>
</div>
@@ -901,8 +849,6 @@ const App: React.FC = () => {
top50Ranking={top50Ranking2025}
velocityMap={velocityMap}
buyBoxLostMap={buyBoxLostMap}
experimentMap={experimentMap}
onOpenExperiment={() => setView('experiments')}
/>
</div>
</Suspense>
@@ -964,30 +910,6 @@ const App: React.FC = () => {
</div>
</Suspense>
<Suspense fallback={<LoadingSpinner />}>
<div className={view === 'experiments' ? '' : 'hidden'}>
<ExperimentsView
salesData={unfilteredCombinedData}
onExperimentsFetch={handleExperimentsFetch}
/>
</div>
</Suspense>
<Suspense fallback={<LoadingSpinner />}>
<div className={view === 'mkt' ? '' : 'hidden'}>
<MktDataView
rawData={filteredData}
adsData={mktAdsData}
stockMap={stockMap}
vendorStockMap={vendorStockMap}
top50Mode={filters.customer.includes('Amazon UK') ? 'uk' : 'eu'}
velocityMap={velocityMap}
buyBoxLostMap={buyBoxLostMap}
top50Ranking={top50Ranking2025}
/>
</div>
</Suspense>
</div>
</>
)}
@@ -998,16 +920,14 @@ const App: React.FC = () => {
{/* Mobile Bottom Navigation */}
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-slate-950/95 backdrop-blur border-t border-border md:hidden pb-safe">
<div className="grid grid-cols-8 gap-0">
<div className="grid grid-cols-6 gap-0">
{([
{ key: 'dashboard' as const, icon: <ChartIcon />, label: 'Home' },
{ key: 'table' as const, icon: <TableIcon />, label: 'Grid' },
{ key: 'weekly' as const, icon: <TrendingIcon />, label: 'Weekly' },
{ key: 'ads' as const, icon: <MegaphoneIcon />, label: 'Ads' },
{ key: 'forecast' as const, icon: <ChartIcon />, label: 'Fc 26' },
{ key: 'mkt' as const, icon: <ChartIcon />, label: 'MKT' },
{ key: 'vendor' as const, icon: <ChartIcon />, label: 'BSR' },
{ key: 'experiments' as const, icon: <span className="text-lg">🧪</span>, label: 'Exp' },
]).map(({ key, icon, label }) => (
<button
key={key}
@@ -1051,8 +971,6 @@ const App: React.FC = () => {
)
}
{/* Experiment modals removed — detail/create are now inline in ExperimentsView */}
</div >
);
};