Rocky_Mountain_Vending/components/product-card.tsx
DMleadgen 46d973904b
Initial commit: Rocky Mountain Vending website
Next.js website for Rocky Mountain Vending company featuring:
- Product catalog with Stripe integration
- Service areas and parts pages
- Admin dashboard with Clerk authentication
- SEO optimized pages with JSON-LD structured data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 16:22:15 -07:00

48 lines
1.6 KiB
TypeScript

import Link from 'next/link'
import Image from 'next/image'
import { Card, CardContent } from '@/components/ui/card'
import type { Product } from '@/lib/products/types'
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}`}>
<Card className="border-border/50 overflow-hidden hover:border-secondary/50 hover:shadow-lg transition-shadow transition-colors h-full flex flex-col">
<div className="aspect-square relative overflow-hidden bg-muted">
<Image
src={imageUrl}
alt={product.name}
fill
className="object-cover hover:scale-105 transition-transform duration-300"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
<CardContent className="p-6 flex flex-col flex-1">
<h3 className="text-xl font-semibold mb-2">{product.name}</h3>
{description && (
<p className="text-sm text-muted-foreground leading-relaxed mb-4 flex-1">
{description}
</p>
)}
<div className="mt-auto">
<p className="text-2xl font-bold text-secondary">
${product.price.toFixed(2)} {product.currency.toUpperCase()}
</p>
</div>
</CardContent>
</Card>
</Link>
)
}