Add src/components/ProductCard.tsx
This commit is contained in:
73
src/components/ProductCard.tsx
Normal file
73
src/components/ProductCard.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
|
||||
interface StripeProduct {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
images: string[];
|
||||
default_price: {
|
||||
id: string;
|
||||
unit_amount: number;
|
||||
currency: string;
|
||||
} | null;
|
||||
metadata: Record<string, string>;
|
||||
}
|
||||
|
||||
interface ProductCardProps {
|
||||
product: StripeProduct;
|
||||
onCheckout: (productId: string, priceId: string) => void;
|
||||
}
|
||||
|
||||
export default function ProductCard({ product, onCheckout }: ProductCardProps) {
|
||||
const formatPrice = (amount: number, currency: string) => {
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: currency.toUpperCase(),
|
||||
}).format(amount / 100);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="flex flex-col h-full overflow-hidden hover:shadow-lg transition-shadow">
|
||||
{product.images[0] && (
|
||||
<div className="relative aspect-square overflow-hidden">
|
||||
<Image
|
||||
src={product.images[0]}
|
||||
alt={product.name}
|
||||
fill
|
||||
className="object-cover hover:scale-105 transition-transform duration-300"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<CardHeader className="flex-none">
|
||||
<CardTitle className="line-clamp-1">{product.name}</CardTitle>
|
||||
{product.default_price && (
|
||||
<p className="text-2xl font-bold text-primary">
|
||||
{formatPrice(product.default_price.unit_amount, product.default_price.currency)}
|
||||
</p>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1">
|
||||
{product.description && (
|
||||
<CardDescription className="line-clamp-3">{product.description}</CardDescription>
|
||||
)}
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => {
|
||||
if (product.default_price) {
|
||||
onCheckout(product.id, product.default_price.id);
|
||||
}
|
||||
}}
|
||||
disabled={!product.default_price}
|
||||
>
|
||||
{product.default_price ? 'Buy Now' : 'Unavailable'}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user