PriceNova

import { useState, useEffect, useRef } from "react"; // ─── Mock Data & Helpers ─────────────────────────────────────────────────────── const SAMPLE_PRODUCTS = [ { asin: "B08N5WRWNW", title: "Apple AirPods Pro (2nd Generation)", brand: "Apple", category: "Electronics", image: "🎧", currentPrice: 189.99, originalPrice: 249.00, rating: 4.7, reviews: 84312, bsr: 3, }, { asin: "B0BDHX8Z63", title: "Sony WH-1000XM5 Wireless Headphones", brand: "Sony", category: "Electronics", image: "🎵", currentPrice: 278.00, originalPrice: 399.99, rating: 4.6, reviews: 41200, bsr: 7, }, { asin: "B09G9FPHY6", title: "Kindle Paperwhite (16 GB)", brand: "Amazon", category: "Electronics", image: "📖", currentPrice: 99.99, originalPrice: 139.99, rating: 4.8, reviews: 128900, bsr: 2, }, { asin: "B0CMDWC436", title: "Instant Pot Duo 7-in-1 Electric Pressure Cooker", brand: "Instant Pot", category: "Kitchen", image: "🍲", currentPrice: 59.99, originalPrice: 99.95, rating: 4.7, reviews: 215400, bsr: 1, }, ]; function generatePriceHistory(basePrice, days = 365) { const history = []; let price = basePrice * 1.15; const now = Date.now(); for (let i = days; i >= 0; i--) { const t = now - i * 86400000; const spike = Math.random() < 0.05 ? (Math.random() * 0.3 - 0.15) : 0; const drift = (Math.random() - 0.5) * 0.02; price = Math.max(basePrice * 0.7, Math.min(basePrice * 1.4, price * (1 + drift + spike))); if (i % 30 < 5) price = basePrice * (0.88 + Math.random() * 0.06); // sale events history.push({ t, price: Math.round(price * 100) / 100 }); } return history; } function dealScore(product) { const discount = (product.originalPrice - product.currentPrice) / product.originalPrice; const ratingScore = (product.rating - 3) / 2; const reviewScore = Math.min(product.reviews / 100000, 1); const bsrScore = 1 - Math.min(product.bsr / 20, 1); return Math.round((discount * 40 + ratingScore * 25 + reviewScore * 20 + bsrScore * 15)); } // ─── Mini Chart ─────────────────────────────────────────────────────────────── function PriceChart({ history, currentPrice, color = "#00ff88" }) { const W = 480, H = 110; if (!history || history.length === 0) return null; const prices = history.map(h => h.price); const minP = Math.min(...prices) * 0.98; const maxP = Math.max(...prices) * 1.02; const toX = (i) => (i / (history.length - 1)) * W; const toY = (p) => H - ((p - minP) / (maxP - minP)) * H; const points = history.map((h, i) => `${toX(i)},${toY(h.price)}`).join(" "); const fillPoints = `0,${H} ` + points + ` ${W},${H}`; const currentY = toY(currentPrice); return ( ); } // ─── Deal Score Badge ────────────────────────────────────────────────────────── function ScoreBadge({ score }) { const color = score >= 75 ? "#00ff88" : score >= 50 ? "#ffcc00" : "#ff6b6b"; const label = score >= 75 ? "HOT" : score >= 50 ? "GOOD" : "FAIR"; return (
{label} {score}
); } // ─── AI Insight Panel ───────────────────────────────────────────────────────── function AIInsightPanel({ product, history }) { const [insight, setInsight] = useState(""); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); async function fetchInsight() { if (insight) { setOpen(true); return; } setLoading(true); setOpen(true); const minP = Math.min(...history.map(h => h.price)); const maxP = Math.max(...history.map(h => h.price)); const avgP = history.reduce((s, h) => s + h.price, 0) / history.length; const prompt = `You are a sharp Amazon deal analyst. Analyze this product and give a crisp, actionable 3-sentence insight. No fluff. Product: ${product.title} Brand: ${product.brand} Category: ${product.category} Current Price: $${product.currentPrice} Original/List Price: $${product.originalPrice} 30-day Price Range: $${minP.toFixed(2)} – $${maxP.toFixed(2)} Average Price (365d): $${avgP.toFixed(2)} Rating: ${product.rating}/5 (${product.reviews.toLocaleString()} reviews) Best Seller Rank: #${product.bsr} in ${product.category} Deal Score: ${dealScore(product)}/100 Give: 1) Is this actually a good deal right now? 2) Price trend prediction. 3) Should the buyer act now or wait?`; try { const res = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 1000, messages: [{ role: "user", content: prompt }], }), }); const data = await res.json(); const text = data.content?.filter(b => b.type === "text").map(b => b.text).join("") || "No insight available."; setInsight(text); } catch (e) { setInsight("Failed to load AI insight. Please try again."); } setLoading(false); } return (
{open && (
{loading ? (
Analyzing with AI...
) : (
✦ AI ANALYSIS
{insight}
)}
)}
); } // ─── Product Card ────────────────────────────────────────────────────────────── function ProductCard({ product, onSelect, selected }) { const score = dealScore(product); const discount = Math.round((1 - product.currentPrice / product.originalPrice) * 100); const history = useRef(generatePriceHistory(product.currentPrice)).current; return (
onSelect({ product, history })} style={{ background: selected ? "rgba(0,255,136,0.04)" : "rgba(255,255,255,0.03)", border: `1.5px solid ${selected ? "rgba(0,255,136,0.4)" : "rgba(255,255,255,0.08)"}`, borderRadius: 14, padding: "16px", cursor: "pointer", transition: "all 0.2s", }} >
{product.image}
{product.title}
{product.brand} · {product.category}
${product.currentPrice} ${product.originalPrice} -{discount}%
★ {product.rating} · {product.reviews.toLocaleString()} reviews · BSR #{product.bsr}
); } // ─── Detail Panel ────────────────────────────────────────────────────────────── function DetailPanel({ data }) { const { product, history } = data; const prices = history.map(h => h.price); const minP = Math.min(...prices); const maxP = Math.max(...prices); const avgP = prices.reduce((s, p) => s + p, 0) / prices.length; const score = dealScore(product); const discount = Math.round((1 - product.currentPrice / product.originalPrice) * 100); const [range, setRange] = useState(90); const filteredHistory = history.slice(-range); return (
{product.image}
{product.title}
ASIN: {product.asin} · {product.brand}
{/* Price Metrics */}
{[ { label: "Current", value: `$${product.currentPrice}`, color: "#00ff88" }, { label: "All-time Low", value: `$${minP.toFixed(2)}`, color: "#60a5fa" }, { label: "All-time High", value: `$${maxP.toFixed(2)}`, color: "#f87171" }, { label: "Avg (1yr)", value: `$${avgP.toFixed(2)}`, color: "#fbbf24" }, ].map(m => (
{m.label.toUpperCase()}
{m.value}
))}
{/* Chart */}
PRICE HISTORY
{[30, 90, 180, 365].map(d => ( ))}
{/* Extra stats */}
DEAL BREAKDOWN
Discount -{discount}%
You save ${(product.originalPrice - product.currentPrice).toFixed(2)}
vs Avg {product.currentPrice < avgP ? "↓" : "↑"} ${Math.abs(product.currentPrice - avgP).toFixed(2)}
PRODUCT STATS
Rating ★ {product.rating}
Reviews {product.reviews.toLocaleString()}
BSR #{product.bsr}
{/* AI Section */}
); } // ─── Search Bar ─────────────────────────────────────────────────────────────── function SearchBar({ query, setQuery }) { return (
setQuery(e.target.value)} placeholder="Search products or paste ASIN..." style={{ width: "100%", background: "rgba(255,255,255,0.05)", border: "1.5px solid rgba(255,255,255,0.1)", borderRadius: 10, padding: "11px 16px 11px 40px", color: "#e8e8e8", fontSize: 14, outline: "none", boxSizing: "border-box", fontFamily: "inherit", }} />
); } // ─── Main App ────────────────────────────────────────────────────────────────── export default function App() { const [query, setQuery] = useState(""); const [selected, setSelected] = useState(null); const [tab, setTab] = useState("tracker"); const [alertList, setAlertList] = useState([ { product: SAMPLE_PRODUCTS[0], targetPrice: 179 }, { product: SAMPLE_PRODUCTS[2], targetPrice: 89 }, ]); const [newAlert, setNewAlert] = useState({ asin: "", price: "" }); const filtered = SAMPLE_PRODUCTS.filter(p => p.title.toLowerCase().includes(query.toLowerCase()) || p.brand.toLowerCase().includes(query.toLowerCase()) || p.asin.toLowerCase().includes(query.toLowerCase()) ); useEffect(() => { const style = document.createElement("style"); style.textContent = ` @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Syne:wght@400;600;700;800&display=swap'); * { box-sizing: border-box; margin: 0; padding: 0; } body { background: #0a0a0f; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } ::-webkit-scrollbar { width: 4px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: #222; border-radius: 4px; } input::placeholder { color: #444; } `; document.head.appendChild(style); return () => document.head.removeChild(style); }, []); return (
{/* Header */}
PriceNova
AI PRICE INTELLIGENCE
{["tracker", "alerts", "compare"].map(t => ( ))}
{/* ── TRACKER TAB ── */} {tab === "tracker" && (
{filtered.map(p => ( setSelected(selected?.product.asin === p.asin ? null : d)} /> ))}
{selected && (
)}
)} {/* ── ALERTS TAB ── */} {tab === "alerts" && (
Price Alerts
Get notified when prices drop to your target
+ ADD ALERT
setNewAlert(a => ({ ...a, asin: e.target.value }))} placeholder="ASIN or product name" style={{ flex: 2, background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 8, padding: "9px 12px", color: "#e8e8e8", fontSize: 13, outline: "none", fontFamily: "inherit" }} /> setNewAlert(a => ({ ...a, price: e.target.value }))} placeholder="Target $" type="number" style={{ flex: 1, background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 8, padding: "9px 12px", color: "#e8e8e8", fontSize: 13, outline: "none", fontFamily: "inherit" }} />
{alertList.map((a, i) => { const triggered = a.product.currentPrice <= a.targetPrice; return (
{a.product.image}
{a.product.title}
Target: ${a.targetPrice} · Current: ${a.product.currentPrice}
{triggered && ✓ TRIGGERED}
); })}
)} {/* ── COMPARE TAB ── */} {tab === "compare" && (
Compare Products
Side-by-side deal analysis
{["PRICE", "ORIGINAL", "DISCOUNT", "RATING", "REVIEWS", "BSR", "DEAL SCORE"].map(h => ( ))} {SAMPLE_PRODUCTS.map((p, i) => { const score = dealScore(p); const discount = Math.round((1 - p.currentPrice / p.originalPrice) * 100); const isTop = score === Math.max(...SAMPLE_PRODUCTS.map(dealScore)); return ( ); })}
PRODUCT{h}
{p.image}
{p.title.slice(0, 36)}…
{p.brand}
{isTop && BEST}
${p.currentPrice} ${p.originalPrice} -{discount}% ★ {p.rating} {p.reviews.toLocaleString()} #{p.bsr}
)}
); }

Comments

Popular posts from this blog

16 May 2012 | Punar Vivah ZEE TV | Watch Online

17 May 2012 | Pratigya Star Plus | Watch Online

16 May 2012 | Ruk jaana nahin Star Plus | Watch Online