mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 13:45:23 +02:00
fix: prevent BuyBox badge visual duplication
- Wrap component with memo() to prevent unnecessary re-renders - Restructure DOM hierarchy to avoid nested inline-flex containers - Center hover popup with left-1/2 -translate-x-1/2 - Add pointer-events-none to popup to prevent hover flickering - Improve popup spacing and sizing Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
co-authored by
Qwen-Coder
parent
c58b246c41
commit
826688a3f6
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, memo } from 'react';
|
||||||
|
|
||||||
interface BuyBoxWarningBadgeProps {
|
interface BuyBoxWarningBadgeProps {
|
||||||
asin: string;
|
asin: string;
|
||||||
@@ -13,7 +13,7 @@ const COUNTRY_FLAGS: Record<string, string> = {
|
|||||||
ES: '🇪🇸',
|
ES: '🇪🇸',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BuyBoxWarningBadge: React.FC<BuyBoxWarningBadgeProps> = ({ asin, buyBoxLostMap }) => {
|
export const BuyBoxWarningBadge: React.FC<BuyBoxWarningBadgeProps> = memo(({ asin, buyBoxLostMap }) => {
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
|
||||||
if (!buyBoxLostMap || !asin) return null;
|
if (!buyBoxLostMap || !asin) return null;
|
||||||
@@ -27,45 +27,45 @@ export const BuyBoxWarningBadge: React.FC<BuyBoxWarningBadgeProps> = ({ asin, bu
|
|||||||
if (!data || data.countries.length === 0) return null;
|
if (!data || data.countries.length === 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="inline-block">
|
||||||
className="relative inline-flex"
|
<div
|
||||||
onMouseEnter={() => setIsHovered(true)}
|
className="relative inline-flex items-center gap-1 px-1.5 h-5 rounded bg-amber-500/20 border border-amber-500/50 text-amber-400 text-[9px] font-bold uppercase tracking-tight cursor-help transition-all hover:bg-amber-500/30 hover:scale-105 whitespace-nowrap"
|
||||||
onMouseLeave={() => setIsHovered(false)}
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
>
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
<div className="inline-flex items-center gap-1 px-1.5 h-5 rounded bg-amber-500/20 border border-amber-500/50 text-amber-400 text-[9px] font-bold uppercase tracking-tight cursor-help transition-all hover:bg-amber-500/30 hover:scale-105 whitespace-nowrap">
|
>
|
||||||
<span className="text-xs leading-none">⚠️</span>
|
<span className="text-xs leading-none">⚠️</span>
|
||||||
<span>BB Lost</span>
|
<span>BB Lost</span>
|
||||||
<span className="text-amber-300/80">{data.countries.slice(0, 3).join(', ')}{data.countries.length > 3 ? '...' : ''}</span>
|
<span className="text-amber-300/80">{data.countries.slice(0, 3).join(', ')}{data.countries.length > 3 ? '...' : ''}</span>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Hover Popup */}
|
{/* Hover Popup */}
|
||||||
{isHovered && (
|
{isHovered && (
|
||||||
<div className="absolute z-[100] left-0 bottom-full mb-1 w-64 bg-slate-900 border border-amber-500/50 rounded-xl shadow-2xl shadow-black animate-fade-in overflow-hidden">
|
<div className="absolute z-[100] left-1/2 -translate-x-1/2 bottom-full mb-2 w-72 bg-slate-900 border border-amber-500/50 rounded-xl shadow-2xl shadow-black overflow-hidden pointer-events-none">
|
||||||
<div className="bg-amber-500/20 px-3 py-2 border-b border-white/10">
|
<div className="bg-amber-500/20 px-4 py-2.5 border-b border-white/10">
|
||||||
<span className="text-amber-400 text-[10px] font-black uppercase tracking-widest flex items-center gap-2">
|
<span className="text-amber-400 text-[11px] font-black uppercase tracking-widest flex items-center gap-2">
|
||||||
<span>⚠️</span> Buy Box Lost Reason
|
<span>⚠️</span> Buy Box Lost Reason
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-2 space-y-1">
|
<div className="p-3 space-y-2 max-h-64 overflow-y-auto">
|
||||||
{data.countries.map(country => (
|
{data.countries.map(country => (
|
||||||
<div
|
<div
|
||||||
key={country}
|
key={country}
|
||||||
className="flex items-start gap-2.5 px-3 py-2 rounded-lg bg-white/5 border border-white/5"
|
className="flex items-start gap-3 px-3 py-2.5 rounded-lg bg-white/5 border border-white/5"
|
||||||
>
|
>
|
||||||
<span className="text-lg leading-none">{COUNTRY_FLAGS[country] || '🏳️'}</span>
|
<span className="text-xl leading-none">{COUNTRY_FLAGS[country] || '🏳️'}</span>
|
||||||
<div className="flex flex-col min-w-0">
|
<div className="flex flex-col min-w-0">
|
||||||
<span className="text-[10px] font-black text-white uppercase tracking-tight opacity-60">
|
<span className="text-[10px] font-black text-white uppercase tracking-tight opacity-60">
|
||||||
{country}
|
{country}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs font-bold text-amber-200 leading-tight">
|
<span className="text-xs font-bold text-amber-200 leading-tight">
|
||||||
{data.reasons[country] || 'Unknown'}
|
{data.reasons[country] || 'Unknown'}
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user