Rocky_Mountain_Vending/components/product-card.tsx

49 lines
1.9 KiB
TypeScript

import Link from "next/link"
import Image from "next/image"
import type { Product } from "@/lib/products/types"
import { PublicInset, PublicSurface } from "@/components/public-surface"
interface ProductCardProps {
product: Product
}
export function ProductCard({ product }: ProductCardProps) {
const imageUrl = product.images?.[0] || "/placeholder.svg"
const description = product.description
? product.description.length > 120
? `${product.description.substring(0, 120)}...`
: product.description
: ""
return (
<Link href={`/products/${product.id}`} className="group block h-full">
<PublicSurface className="h-full overflow-hidden p-0 transition-all group-hover:-translate-y-0.5 group-hover:shadow-[0_26px_65px_rgba(0,0,0,0.12)]">
<div className="relative aspect-square overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(196,154,52,0.14),transparent_55%),linear-gradient(180deg,rgba(247,244,236,0.72),rgba(255,255,255,0.96))]">
<Image
src={imageUrl}
alt={product.name}
fill
className="object-cover transition-transform duration-300 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
<div className="p-5 md:p-6">
<h3 className="text-xl font-semibold mb-2">{product.name}</h3>
{description ? (
<p className="mb-4 text-sm leading-relaxed text-muted-foreground">
{description}
</p>
) : null}
<PublicInset className="mt-auto">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-primary/75">
Starting at
</p>
<p className="mt-2 text-2xl font-bold text-foreground">
${product.price.toFixed(2)} {product.currency.toUpperCase()}
</p>
</PublicInset>
</div>
</PublicSurface>
</Link>
)
}