Update app/product/[id]/page.tsx

This commit is contained in:
kleap-admin 2026-01-18 13:40:28 +00:00
parent 765b65de32
commit 510dbc1d9c
1 changed files with 261 additions and 0 deletions

261
app/product/[id]/page.tsx Normal file
View File

@ -0,0 +1,261 @@
"use client";
import { Container } from "@/components/container";
import { Footer } from "@/components/footer";
import { Button } from "@/components/ui/button";
import { BlurImage } from "@/components/blur-image";
import { Badge } from "@/components/badge";
import { useState } from "react";
import { ProductCard } from "@/components/product-card";
// Mock product data - in real app, this would come from API/database
const productData = {
id: "1",
name: "Modern Velvet Sofa",
price: 899,
originalPrice: 1299,
category: "Living Room",
description: "Elevate your living space with our luxurious Modern Velvet Sofa. Featuring plush velvet upholstery, deep cushioning, and a sturdy hardwood frame, this sofa combines comfort with contemporary style. Perfect for relaxing after a long day or entertaining guests.",
features: [
"Premium velvet upholstery",
"Solid hardwood frame",
"High-density foam cushions",
"Removable cushion covers",
"Weight capacity: 800 lbs",
"Assembly required (30 minutes)",
],
dimensions: {
width: "84 inches",
depth: "36 inches",
height: "33 inches",
seatHeight: "18 inches",
},
colors: ["Navy Blue", "Emerald Green", "Charcoal Gray", "Blush Pink"],
images: [
"https://images.unsplash.com/photo-1555041469-a586c61ea9bc?w=800&q=80",
"https://images.unsplash.com/photo-1540574163026-643ea20ade25?w=800&q=80",
"https://images.unsplash.com/photo-1567538096630-e0c55bd6374c?w=800&q=80",
],
inStock: true,
rating: 4.8,
reviews: 127,
};
const relatedProducts = [
{
id: "5",
name: "Minimalist Coffee Table",
price: 299,
image: "https://images.unsplash.com/photo-1532372320572-cda25653a26d?w=600&q=80",
category: "Living Room",
},
{
id: "6",
name: "Leather Recliner",
price: 799,
originalPrice: 999,
image: "https://images.unsplash.com/photo-1567538096630-e0c55bd6374c?w=600&q=80",
category: "Living Room",
isSale: true,
},
{
id: "12",
name: "Accent Armchair",
price: 399,
image: "https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=600&q=80",
category: "Living Room",
},
];
export default function ProductDetailPage() {
const [selectedImage, setSelectedImage] = useState(0);
const [selectedColor, setSelectedColor] = useState(productData.colors[0]);
const [quantity, setQuantity] = useState(1);
const discount = productData.originalPrice
? Math.round(((productData.originalPrice - productData.price) / productData.originalPrice) * 100)
: 0;
return (
<>
<section className="py-12">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 mb-20">
{/* Product Images */}
<div>
<div className="relative h-[500px] rounded-2xl overflow-hidden mb-4">
<BlurImage
src={productData.images[selectedImage]}
alt={productData.name}
fill
className="object-cover"
/>
{discount > 0 && (
<div className="absolute top-4 right-4">
<Badge variant="destructive">-{discount}%</Badge>
</div>
)}
</div>
<div className="grid grid-cols-3 gap-4">
{productData.images.map((image, index) => (
<button
key={index}
onClick={() => setSelectedImage(index)}
className={`relative h-32 rounded-lg overflow-hidden border-2 transition-all ${
selectedImage === index
? "border-neutral-900 dark:border-neutral-100"
: "border-transparent hover:border-neutral-300"
}`}
>
<BlurImage
src={image}
alt={`${productData.name} view ${index + 1}`}
fill
className="object-cover"
/>
</button>
))}
</div>
</div>
{/* Product Info */}
<div>
<p className="text-sm text-neutral-500 dark:text-neutral-400 uppercase tracking-wide mb-2">
{productData.category}
</p>
<h1 className="text-4xl font-bold mb-4">{productData.name}</h1>
<div className="flex items-center gap-4 mb-6">
<div className="flex items-center gap-2">
<span className="text-3xl font-bold">${productData.price}</span>
{productData.originalPrice && (
<span className="text-xl text-neutral-500 line-through">
${productData.originalPrice}
</span>
)}
</div>
<div className="flex items-center gap-1">
<span className="text-yellow-500"></span>
<span className="font-semibold">{productData.rating}</span>
<span className="text-neutral-500">({productData.reviews} reviews)</span>
</div>
</div>
<p className="text-neutral-600 dark:text-neutral-400 mb-6">
{productData.description}
</p>
{/* Color Selection */}
<div className="mb-6">
<p className="font-semibold mb-3">Color: {selectedColor}</p>
<div className="flex gap-2">
{productData.colors.map((color) => (
<button
key={color}
onClick={() => setSelectedColor(color)}
className={`px-4 py-2 rounded-lg border-2 transition-all ${
selectedColor === color
? "border-neutral-900 dark:border-neutral-100 bg-neutral-100 dark:bg-neutral-800"
: "border-neutral-200 dark:border-neutral-700 hover:border-neutral-400"
}`}
>
{color}
</button>
))}
</div>
</div>
{/* Quantity */}
<div className="mb-6">
<p className="font-semibold mb-3">Quantity</p>
<div className="flex items-center gap-4">
<Button
variant="outline"
onClick={() => setQuantity(Math.max(1, quantity - 1))}
>
-
</Button>
<span className="text-xl font-semibold w-12 text-center">{quantity}</span>
<Button
variant="outline"
onClick={() => setQuantity(quantity + 1)}
>
+
</Button>
</div>
</div>
{/* Add to Cart */}
<div className="flex gap-4 mb-8">
<Button size="lg" className="flex-1">
Add to Cart - ${productData.price * quantity}
</Button>
<Button size="lg" variant="outline">
</Button>
</div>
{/* Stock Status */}
{productData.inStock ? (
<p className="text-green-600 dark:text-green-400 mb-6">
In Stock - Ships within 2-3 business days
</p>
) : (
<p className="text-red-600 dark:text-red-400 mb-6">
Out of Stock - Notify me when available
</p>
)}
{/* Features */}
<div className="border-t pt-6">
<h3 className="font-semibold text-lg mb-4">Key Features</h3>
<ul className="space-y-2">
{productData.features.map((feature, index) => (
<li key={index} className="flex items-start gap-2">
<span className="text-green-600 dark:text-green-400 mt-1"></span>
<span className="text-neutral-600 dark:text-neutral-400">{feature}</span>
</li>
))}
</ul>
</div>
{/* Dimensions */}
<div className="border-t mt-6 pt-6">
<h3 className="font-semibold text-lg mb-4">Dimensions</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-neutral-500">Width</p>
<p className="font-semibold">{productData.dimensions.width}</p>
</div>
<div>
<p className="text-sm text-neutral-500">Depth</p>
<p className="font-semibold">{productData.dimensions.depth}</p>
</div>
<div>
<p className="text-sm text-neutral-500">Height</p>
<p className="font-semibold">{productData.dimensions.height}</p>
</div>
<div>
<p className="text-sm text-neutral-500">Seat Height</p>
<p className="font-semibold">{productData.dimensions.seatHeight}</p>
</div>
</div>
</div>
</div>
</div>
{/* Related Products */}
<div>
<h2 className="text-3xl font-bold mb-8">You May Also Like</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{relatedProducts.map((product) => (
<ProductCard key={product.id} {...product} />
))}
</div>
</div>
</Container>
</section>
<Footer />
</>
);
}