// product-detail.jsx — Página de detalhe do produto com gráfico de histórico const { useState: useStatePD, useMemo: useMemoPD } = React; function ProductDetail({ product, onBack, onProduct }) { const [period, setPeriod] = useStatePD("180"); const [showAlert, setShowAlert] = useStatePD(false); const [target, setTarget] = useStatePD(Math.round(product.lowestEver * 0.97)); // Gera ofertas multi-loja a partir do título do produto const multiOffers = useMemoPD(() => { const t = encodeURIComponent(product.title); const td = encodeURIComponent(product.title.replace(/ /g, "-")); const stores = [ { store: "amz", storeName: "Amazon", price: product.current, pix: Math.round(product.current * 0.95), ship: "Prime grátis", link: `https://www.amazon.com.br/s?k=${t}&tag=yetishopping-20` }, { store: "ml", storeName: "Mercado Livre", price: Math.round(product.current*1.03), pix: Math.round(product.current*1.03*0.95), ship: "Ver condições", link: `https://lista.mercadolivre.com.br/${td}` }, { store: "kbm", storeName: "Kabum", price: Math.round(product.current*0.98), pix: Math.round(product.current*0.98*0.92), ship: "Frete grátis", link: `https://www.kabum.com.br/busca/${td}` }, { store: "mglu", storeName: "Magalu", price: Math.round(product.current*1.01), pix: Math.round(product.current*1.01*0.95), ship: "Frete grátis", link: `https://www.magazineluiza.com.br/busca/${td}/` }, { store: "shp", storeName: "Shopee", price: Math.round(product.current*0.96), pix: Math.round(product.current*0.96*0.95), ship: "Grátis", link: `https://shopee.com.br/search?keyword=${t}` }, ].sort((a, b) => a.price - b.price); return stores; }, [product]); const sortedOffers = multiOffers; const cheapest = sortedOffers[0]; const savedFromBase = product.base - product.current; const savedPct = Math.round((savedFromBase / product.base) * 100); const isAtLow = product.current <= product.lowestEver * 1.03; // Produtos relacionados: buscados em tempo real pela categoria via YetiAPI const [relatedProducts, setRelatedProducts] = React.useState([]); React.useEffect(() => { const cat = CATEGORIES?.find(c => c.id === product.cat); const kw = cat?.keyword || product.category || "oferta"; if (window.YetiAPI) { YetiAPI.search(kw, { size: 8 }) .then(results => setRelatedProducts(results.filter(p => p.id !== product.id).slice(0, 4))) .catch(() => setRelatedProducts([])); } }, [product.id]); return (
{/* Breadcrumb */}
{product.category} {product.title}
{/* Top section: image + main info */}
{/* Image gallery */}
{savedPct >= 10 && (
−{savedPct}%
)}
{[0, 1, 2, 3].map(i => (
))}
{/* Info */}
{product.brand}·{product.category}

{product.title}

{product.rating && (
★★★★★ {product.rating} {product.reviews && ({product.reviews.toLocaleString("pt-BR")} avaliações)}
)} {product.rating && |} Comparando {product.offers?.length ?? 1} {(product.offers?.length ?? 1) === 1 ? "loja" : "lojas"}
{/* Big price panel */}
Melhor preço hoje ·
{fmtBRL(cheapest.price)}
{fmtBRL(product.base)}
{fmtBRL(cheapest.pix)} no Pix ou 12x de {fmtBRL2(cheapest.price / 12)}
{/* Multi-lojas: busca o produto em cada loja */} {[ { name: "Amazon", color: "#FF9900", text: "#131A22", url: `https://www.amazon.com.br/s?k=${encodeURIComponent(product.title)}&tag=yetishopping-20` }, { name: "Mercado Livre",color: "#FFE600", text: "#2D3277", url: `https://lista.mercadolivre.com.br/${encodeURIComponent(product.title.replace(/ /g,"-"))}` }, { name: "Kabum", color: "#FF6500", text: "#FFFFFF", url: `https://www.kabum.com.br/busca/${encodeURIComponent(product.title.replace(/ /g,"-"))}` }, { name: "Magalu", color: "#0086FF", text: "#FFFFFF", url: `https://www.magazineluiza.com.br/busca/${encodeURIComponent(product.title.replace(/ /g,"-"))}/` }, { name: "Shopee", color: "#EE4D2D", text: "#FFFFFF", url: `https://shopee.com.br/search?keyword=${encodeURIComponent(product.title)}` }, ].map((s, i) => ( Buscar no {s.name} ))}
{/* Verdict */}
{isAtLow ? "🤙" : "🤔"}
{isAtLow ? "Veredito do Yeti: COMPRA!" : "Veredito do Yeti: Pode esperar"}
{isAtLow ? `Tá no menor preço dos últimos ${period === "all" ? "180" : period} dias. Bora!` : `Já esteve a ${fmtBRL(product.lowestEver)} (${new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "short" }).format(product.lowestDate)}). Vale esperar uma queda.`}
{/* Alert form expanding */} {showAlert && (
Me avise quando o preço cair para:
setTarget(parseInt(e.target.value || "0", 10))} style={{ width: "100%", border: "1.5px solid #0E2A47", borderRadius: 10, padding: "10px 14px 10px 36px", fontSize: 16, fontWeight: 700, fontFamily: "inherit", color: "#0E2A47", outline: "none", fontVariantNumeric: "tabular-nums" }}/> R$
setTarget(parseInt(e.target.value, 10))} style={{ flex: 2 }}/>
Menor histórico: {fmtBRL(product.lowestEver)} Atual: {fmtBRL(product.current)}
)}
{/* Price chart section */}
Histórico de preço

Evolução em {period === "all" ? "180 dias" : `${period} dias`}

{[ { v: "30", l: "30d" }, { v: "90", l: "90d" }, { v: "180", l: "180d" }, { v: "all", l: "Tudo" }, ].map(opt => ( ))}
{[ { label: "Preço atual", value: fmtBRL(product.current), color: "#FFC72C", sub: "agora mesmo" }, { label: "Menor histórico", value: fmtBRL(product.lowestEver), color: "#1FB3A6", sub: new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "short" }).format(product.lowestDate) }, { label: "Maior histórico", value: fmtBRL(product.highestEver), color: "#FF6B5C", sub: new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "short" }).format(product.highestDate) }, { label: "Preço médio", value: fmtBRL(Math.round(product.history.reduce((a, b) => a + b.p, 0) / product.history.length)), color: "#3A4A5E", sub: "últimos 180d" }, ].map((s, i) => (
{s.label}
{s.value}
{s.sub}
))}
{/* Offers comparison table */}
Comparação

Mesmo produto em {product.offers.length} lojas

{sortedOffers.map((o, i) => ( ))}
Loja Preço Pix Parcelado Frete Ação
{i === 0 && ● MELHOR PREÇO}
{fmtBRL(o.price)} {fmtBRL(o.pix)} 12× {fmtBRL2(o.price / 12)} {o.ship} Buscar →
{/* Specs + related side by side */}
Sobre o produto

Informações

    {(product.spec || [ `Categoria: ${product.category || "Geral"}`, `Loja: ${product.storeName || product.brand || "Parceiro"}`, `Menor histórico nos últimos 180 dias: ${fmtBRL(product.lowestEver)}`, `Maior histórico: ${fmtBRL(product.highestEver)}`, "Preços atualizados em tempo real", ]).map((s, i) => (
  • {s}
  • ))}
Relacionados

O Yeti também vigia

{relatedProducts.slice(0, 4).map(p => ( ))}
); } Object.assign(window, { ProductDetail });