import { useState } from "react"; import type { Product } from "@/lib/types"; interface Props { products: Product[]; } function showToast(msg: string) { const t = document.getElementById("toast"); if (!t) return; t.textContent = msg; t.className = "toast success"; setTimeout(() => t.classList.add("show"), 10); setTimeout(() => t.classList.remove("show"), 2500); } export default function ComparePanel({ products }: Props) { const [selected, setSelected] = useState([]); const toggle = (id: string) => { if (selected.includes(id)) { setSelected(selected.filter((x) => x !== id)); } else if (selected.length < 3) { setSelected([...selected, id]); } else { showToast("Select up to 3 products"); } }; const prods = selected .map((id) => products.find((p) => p.id === id)) .filter(Boolean) as Product[]; const bestRating = prods.length ? Math.max(...prods.map((p) => p.rating)) : 0; const bestPrice = prods.length ? Math.min(...prods.map((p) => Math.min(...p.prices.map((pr) => pr.price)))) : 0; const bestReviews = prods.length ? Math.max(...prods.map((p) => p.reviewCount)) : 0; const rows = prods.length >= 2 ? [ { label: "Category", vals: prods.map((p) => p.category) }, { label: "Rating", vals: prods.map((p) => p.rating.toString()), best: prods.map((p) => p.rating === bestRating), }, { label: "Reviews", vals: prods.map((p) => p.reviewCount.toLocaleString()), best: prods.map((p) => p.reviewCount === bestReviews), }, { label: "Best Price", vals: prods.map((p) => { const bp = p.prices.reduce((a, b) => a.price < b.price ? a : b, ); return "$" + bp.price.toFixed(2); }), best: prods.map( (p) => Math.min(...p.prices.map((pr) => pr.price)) === bestPrice, ), }, { label: "Best Store", vals: prods.map((p) => { const bp = p.prices.reduce((a, b) => a.price < b.price ? a : b, ); return bp.store; }), }, { label: "Top Pro", vals: prods.map((p) => p.pros[0]) }, { label: "Top Con", vals: prods.map((p) => p.cons[0]) }, ] : []; return (
{products.map((p) => (
toggle(p.id)} style={{ padding: "8px 14px", background: selected.includes(p.id) ? "var(--blue-bg)" : "var(--surface)", border: selected.includes(p.id) ? "1.5px solid var(--blue)" : "1.5px solid var(--border)", borderRadius: "20px", fontSize: "0.8rem", cursor: "pointer", color: selected.includes(p.id) ? "var(--blue)" : "var(--text2)", transition: "all 0.15s", }} > {p.name}
))}
{selected.length === 1 && (

Select one more product to compare.

)} {prods.length >= 2 && (
{prods.map((p) => ( ))} {rows.map((row) => ( {row.vals.map((val, i) => ( ))} ))}
{p.name}
{row.label} {val}
)}
); } const thStyle: React.CSSProperties = { padding: "10px 14px", textAlign: "left", borderBottom: "1px solid var(--border)", fontSize: "0.75rem", color: "var(--text2)", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em", background: "var(--surface)", }; const tdStyle: React.CSSProperties = { padding: "10px 14px", textAlign: "left", borderBottom: "1px solid var(--border)", fontSize: "0.85rem", background: "var(--surface2)", };