mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 16:45:24 +02:00
feat: mostrar detalles del producto en Vendor tab cuando hay un solo ASIN
- Agregar tarjeta con SKU, ASIN y título al inicio de los gráficos - Incluir Buy Box Warning Badge si el producto tiene issues - Solo se muestra cuando hay un único ASIN seleccionado Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
co-authored by
Qwen-Coder
parent
32a7de8aea
commit
2814d68716
@@ -924,7 +924,7 @@ const App: React.FC = () => {
|
||||
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<div className={view === 'vendor' ? '' : 'hidden'}>
|
||||
<VendorDataView bsrData={filteredBsrData} />
|
||||
<VendorDataView bsrData={filteredBsrData} asinMetadata={globalAsinMetadata} buyBoxLostMap={buyBoxLostMap} />
|
||||
</div>
|
||||
</Suspense>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
|
||||
import { BSRRecord } from '../types';
|
||||
import { BuyBoxWarningBadge } from './BuyBoxWarningBadge';
|
||||
|
||||
const MARKET_COLORS: Record<string, string> = {
|
||||
DE: '#3b82f6',
|
||||
@@ -12,6 +13,8 @@ const MARKET_COLORS: Record<string, string> = {
|
||||
|
||||
interface VendorDataViewProps {
|
||||
bsrData: BSRRecord[];
|
||||
asinMetadata?: Map<string, { sku: string; title: string; line: string }>;
|
||||
buyBoxLostMap?: Map<string, { countries: string[]; reasons: Record<string, string> }>;
|
||||
}
|
||||
|
||||
interface ChartPoint {
|
||||
@@ -20,7 +23,7 @@ interface ChartPoint {
|
||||
[key: string]: number | string | null;
|
||||
}
|
||||
|
||||
const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [] }) => {
|
||||
const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [], asinMetadata, buyBoxLostMap }) => {
|
||||
// Determine active markets in filtered data for series generation
|
||||
const activeMarkets = useMemo(() => {
|
||||
const m = new Set(bsrData.map(r => r.market));
|
||||
@@ -33,6 +36,26 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [] }) => {
|
||||
return withDate > bsrData.length / 2;
|
||||
}, [bsrData]);
|
||||
|
||||
// Get unique ASINs in filtered data
|
||||
const uniqueAsins = useMemo(() => {
|
||||
const asinSet = new Set(bsrData.map(r => r.asin.trim().toUpperCase()));
|
||||
return Array.from(asinSet);
|
||||
}, [bsrData]);
|
||||
|
||||
// Get product info when single ASIN is selected
|
||||
const productInfo = useMemo(() => {
|
||||
if (uniqueAsins.length !== 1) return null;
|
||||
const asin = uniqueAsins[0];
|
||||
const metadata = asinMetadata?.get(asin);
|
||||
if (!metadata) return null;
|
||||
return {
|
||||
asin,
|
||||
sku: metadata.sku,
|
||||
title: metadata.title,
|
||||
line: metadata.line,
|
||||
};
|
||||
}, [uniqueAsins, asinMetadata]);
|
||||
|
||||
// Aggregate Data for Charts — daily if dates available, else weekly
|
||||
const { topBsrChartData, detailBsrChartData, ratingChartData } = useMemo(() => {
|
||||
// Group by date string (YYYY-MM-DD) or by week number
|
||||
@@ -121,6 +144,38 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData = [] }) => {
|
||||
<span className="text-slate-500 text-xs ml-auto">{bsrData.length.toLocaleString()} records filtered</span>
|
||||
</div>
|
||||
|
||||
{/* Product Info Card - Only shown when single ASIN is selected */}
|
||||
{productInfo && (
|
||||
<div className="bg-gradient-to-r from-indigo-500/10 to-purple-500/10 border border-indigo-500/30 rounded-xl p-4 animate-fade-in">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-[10px] font-black text-indigo-400 uppercase tracking-widest bg-indigo-500/20 px-2 py-0.5 rounded">
|
||||
Product Details
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-xs text-slate-500 font-bold uppercase tracking-wider">SKU:</span>
|
||||
<span className="text-sm font-mono font-bold text-slate-200">{productInfo.sku}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-xs text-slate-500 font-bold uppercase tracking-wider">ASIN:</span>
|
||||
<span className="text-sm font-mono font-bold text-indigo-400">{productInfo.asin}</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-xs text-slate-500 font-bold uppercase tracking-wider mt-0.5">Title:</span>
|
||||
<span className="text-sm font-medium text-slate-300">{productInfo.title}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<BuyBoxWarningBadge asin={productInfo.asin} buyBoxLostMap={buyBoxLostMap} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Top Level BSR Trend Chart */}
|
||||
<div className="bg-slate-900/50 border border-slate-800 rounded-xl p-4">
|
||||
<h3 className="text-lg font-bold text-slate-200 mb-4">Top Level BSR Trend ({resolutionLabel})</h3>
|
||||
|
||||
Reference in New Issue
Block a user