lots of fixes. cant remember them all
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
|
||||
type UiPart = {
|
||||
id: string;
|
||||
name: string;
|
||||
brand: string;
|
||||
platform: string;
|
||||
partRole: string;
|
||||
price: number;
|
||||
imageUrl?: string;
|
||||
buyUrl?: string;
|
||||
inStock?: boolean;
|
||||
};
|
||||
|
||||
export default function PartsGrid(props: {
|
||||
viewMode: "card" | "list";
|
||||
parts: UiPart[];
|
||||
buildDetailHref: (p: UiPart) => string;
|
||||
|
||||
// NEW: optional Add-to-Build behavior
|
||||
onAddToBuild?: (p: UiPart) => void;
|
||||
addLabel?: string;
|
||||
}) {
|
||||
const { viewMode, parts, buildDetailHref, onAddToBuild } = props;
|
||||
const addLabel = props.addLabel ?? "Add to Build";
|
||||
|
||||
if (viewMode === "card") {
|
||||
return (
|
||||
<div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
|
||||
{parts.map((part) => (
|
||||
<div
|
||||
key={part.id}
|
||||
className="group relative flex flex-col rounded-md border border-zinc-700 bg-zinc-900/50 p-3 transition-all duration-200 hover:border-amber-400/60 hover:bg-amber-400/10"
|
||||
>
|
||||
<div className="mb-3 flex items-center gap-2 justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-sm font-semibold text-zinc-50 truncate">
|
||||
{part.brand} <span className="font-normal">— {part.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="whitespace-nowrap text-sm font-semibold text-amber-300">
|
||||
${part.price.toFixed(2)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-2 flex gap-2">
|
||||
<Link
|
||||
href={buildDetailHref(part)}
|
||||
className="flex-1 rounded-md border border-zinc-700 bg-zinc-800/50 px-3 py-2 text-center text-xs font-medium text-zinc-300 transition-colors hover:border-zinc-600 hover:bg-zinc-700"
|
||||
>
|
||||
View Details
|
||||
</Link>
|
||||
|
||||
{/* NEW: Add to Build (preferred primary action if provided) */}
|
||||
{onAddToBuild ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onAddToBuild(part)}
|
||||
className="flex-1 rounded-md bg-amber-400 px-3 py-2 text-center text-xs font-semibold text-black hover:bg-amber-300 transition-colors"
|
||||
>
|
||||
{addLabel}
|
||||
</button>
|
||||
) : part.buyUrl ? (
|
||||
<a
|
||||
href={part.buyUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="flex-1 rounded-md bg-amber-400 px-3 py-2 text-center text-xs font-semibold text-black hover:bg-amber-300 transition-colors"
|
||||
>
|
||||
Buy
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
disabled
|
||||
className="flex-1 rounded-md bg-zinc-700 px-3 py-2 text-center text-xs font-semibold text-zinc-200 opacity-50"
|
||||
>
|
||||
No Action
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// LIST view
|
||||
return (
|
||||
<>
|
||||
<div className="hidden grid-cols-[minmax(0,3fr)_minmax(0,1fr)_minmax(0,1fr)_auto] px-3 pb-2 text-[0.7rem] uppercase tracking-[0.16em] text-zinc-500 md:grid">
|
||||
<span>Part</span>
|
||||
<span>Brand</span>
|
||||
<span className="text-right">Price</span>
|
||||
<span className="pr-2 text-right">Actions</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
{parts.map((part) => (
|
||||
<div
|
||||
key={part.id}
|
||||
className="group relative rounded-md border border-zinc-700 bg-zinc-900/50 p-3 transition-all duration-200 hover:border-amber-400/60 hover:bg-amber-400/10"
|
||||
>
|
||||
<div className="flex flex-col gap-2 md:grid md:grid-cols-[minmax(0,3fr)_minmax(0,1fr)_minmax(0,1fr)_auto] md:items-center md:gap-4">
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="text-sm font-semibold text-zinc-50 truncate">
|
||||
{part.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-xs text-zinc-400 md:text-left md:text-sm">
|
||||
{part.brand}
|
||||
</div>
|
||||
|
||||
<div className="text-sm font-semibold text-amber-300 md:text-right">
|
||||
${part.price.toFixed(2)}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<Link
|
||||
href={buildDetailHref(part)}
|
||||
className="whitespace-nowrap rounded-md border border-zinc-700 bg-zinc-800/50 px-3 py-1.5 text-xs font-medium text-zinc-300 transition-colors hover:border-zinc-600 hover:bg-zinc-700"
|
||||
>
|
||||
View Details
|
||||
</Link>
|
||||
|
||||
{onAddToBuild ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onAddToBuild(part)}
|
||||
className="whitespace-nowrap rounded-md bg-amber-400 px-3 py-1.5 text-xs font-semibold text-black hover:bg-amber-300 transition-colors"
|
||||
>
|
||||
{addLabel}
|
||||
</button>
|
||||
) : part.buyUrl ? (
|
||||
<a
|
||||
href={part.buyUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="whitespace-nowrap rounded-md bg-amber-400 px-3 py-1.5 text-xs font-semibold text-black hover:bg-amber-300 transition-colors"
|
||||
>
|
||||
Buy
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
disabled
|
||||
className="whitespace-nowrap rounded-md bg-zinc-700 px-3 py-1.5 text-xs font-semibold text-zinc-200 opacity-50"
|
||||
>
|
||||
No Action
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user