49 lines
1.9 KiB
TypeScript
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>
|
|
)
|
|
}
|