"use client"; import Link from "next/link"; import { Plus } from "lucide-react"; import type { UiPart } from "@/types/uiPart"; import { ProductImage } from './ProductImage'; export default function PartsGrid(props: { viewMode: "card" | "list"; parts: UiPart[]; buildDetailHref: (p: UiPart) => string; onAddToBuild?: (p: UiPart) => void; addLabel?: string; }) { const { viewMode, parts, buildDetailHref, onAddToBuild } = props; const addLabel = props.addLabel ?? "Add to Build"; // ✅ Only show caliber column if we actually have caliber data const showCaliber = parts.some((p) => !!p.caliber); // ✅ Single source of truth for grid columns (prevents header/row drift) // Columns: Image | Part | Brand | (Caliber?) | Price | Actions const gridCols = showCaliber ? "md:grid-cols-[44px_minmax(0,1fr)_160px_120px_110px_120px]" // +Caliber : "md:grid-cols-[44px_minmax(0,1fr)_160px_110px_120px]"; // no Caliber"md:grid-cols-[44px_minmax(0,1fr)_160px_110px_120px]"; const formatPrice = (price?: number | null) => { if (price == null) return "—"; return `$${price.toFixed(2)}`; }; if (viewMode === "card") { return (
{parts.map((part) => { const buyHref = part.buyShortUrl ?? part.buyUrl; return (
{part.brand}{" "} — {part.name}
{formatPrice(part.price)}
View Details {onAddToBuild ? ( ) : buyHref ? ( Buy ) : ( )}
); })}
); } // LIST view return ( <> {/* Header (DESKTOP ONLY) */}
Image Part Brand {showCaliber ? Caliber : null} Price Actions
{/* Rows */}
{parts.map((part) => { const buyHref = part.buyShortUrl ?? part.buyUrl; return (
{/* Image */}
{/* Part */}
{part.name}
{/* Brand */}
{part.brand || "—"}
{/* Caliber (optional) */} {showCaliber ? (
{part.caliber ?? "—"}
) : null} {/* Price */}
{formatPrice(part.price)}
{/* Actions */}
{onAddToBuild ? ( ) : buyHref ? ( Buy ) : ( )}
); })}
); }