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

This commit is contained in:
2026-03-12 06:23:33 +00:00
parent 7041712fde
commit 5bceca6907

View File

@@ -6,7 +6,6 @@ import FooterCard from "@/components/sections/footer/FooterCard";
import { Instagram, Twitter, Youtube, ShoppingCart, Heart } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { useParams } from "next/navigation";
const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
<svg
@@ -21,18 +20,11 @@ const TikTok = (props: React.SVGProps<SVGSVGElement>) => (
</svg>
);
const products = [
{
id: "1", name: "Classic Black Hoodie", price: "$89.99", imageSrc: "http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg", description: "Our signature black hoodie crafted from premium organic cotton blend. Features a relaxed fit, front kangaroo pocket, and reinforced stitching for durability.", details: "Material: 60% organic cotton, 40% polyester | Fit: Oversized | Care: Machine wash cold"},
{
id: "2", name: "Vintage Denim Jacket", price: "$129.99", imageSrc: "http://img.b2bpic.net/free-photo/fashionable-woman-wearing-denim-jacket_23-2148859621.jpg", description: "A timeless denim jacket with authentic vintage vibes. Perfect layering piece for any streetwear aesthetic.", details: "Material: 100% denim | Fit: Relaxed | Care: Machine wash cold"},
];
export default function ProductPage() {
const params = useParams();
const productId = params.id as string;
const product = products.find((p) => p.id === productId) || products[0];
interface PageProps {
params: { id: string };
}
export default function ProductDetailPage({ params }: PageProps) {
const navItems = [
{ name: "Shop", id: "products" },
{ name: "Collections", id: "collections" },
@@ -41,10 +33,32 @@ export default function ProductPage() {
{ name: "Contact", id: "contact" },
];
const [selectedSize, setSelectedSize] = useState("M");
const [quantity, setQuantity] = useState(1);
const [selectedSize, setSelectedSize] = useState("M");
const [selectedColor, setSelectedColor] = useState("Black");
const [isFavorited, setIsFavorited] = useState(false);
const productId = params.id;
const products: Record<string, any> = {
"1": {
id: "1", name: "Classic Black Hoodie", price: 89.99,
description: "Experience ultimate comfort with our signature Classic Black Hoodie. Crafted from premium cotton blend, this versatile piece is perfect for any casual occasion. Features a spacious front pocket and adjustable drawstrings.", imageSrc: "http://img.b2bpic.net/free-photo/medium-shot-man-posing-with-hoodie-indoors_23-2149359859.jpg", sizes: ["XS", "S", "M", "L", "XL", "XXL"],
colors: ["Black", "Navy", "Charcoal"],
rating: 4.8,
reviews: 156,
},
"2": {
id: "2", name: "Vintage Denim Jacket", price: 129.99,
description: "Make a statement with our Vintage Denim Jacket. This timeless piece features authentic fading and distressing for that perfect worn-in look. Premium quality denim with reinforced stitching ensures durability.", imageSrc: "http://img.b2bpic.net/free-photo/fashionable-woman-wearing-denim-jacket_23-2148859621.jpg", sizes: ["XS", "S", "M", "L", "XL"],
colors: ["Indigo", "Light Blue", "Black"],
rating: 4.9,
reviews: 203,
},
};
const product = products[productId] || products["1"];
const socialLinks = [
{ icon: Instagram, href: "https://instagram.com/umbra", ariaLabel: "Instagram" },
{ icon: Twitter, href: "https://twitter.com/umbra", ariaLabel: "Twitter" },
@@ -59,11 +73,11 @@ export default function ProductPage() {
borderRadius="soft"
contentWidth="smallMedium"
sizing="medium"
background="noiseDiagonalGradient"
background="circleGradient"
cardStyle="glass-elevated"
primaryButtonStyle="primary-glow"
secondaryButtonStyle="radial-glow"
headingFontWeight="light"
primaryButtonStyle="gradient"
secondaryButtonStyle="glass"
headingFontWeight="normal"
>
<div id="nav" data-section="nav">
<NavbarStyleCentered
@@ -81,31 +95,43 @@ export default function ProductPage() {
</Link>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="flex items-center justify-center bg-card/30 rounded-soft p-8">
{/* Product Image */}
<div className="flex items-center justify-center bg-card/50 border border-accent/20 rounded-soft p-8 aspect-square">
<img
src={product.imageSrc}
alt={product.name}
className="max-w-md w-full h-auto object-cover rounded-soft"
className="w-full h-full object-cover rounded"
/>
</div>
<div className="flex flex-col justify-start">
<h1 className="text-4xl font-light text-foreground mb-4">{product.name}</h1>
<p className="text-3xl font-bold text-background-accent mb-6">{product.price}</p>
{/* Product Details */}
<div className="flex flex-col justify-center">
<div className="mb-4">
<h1 className="text-4xl font-bold text-foreground mb-2">{product.name}</h1>
<div className="flex items-center gap-2">
<span className="text-background-accent font-semibold">{product.rating}</span>
<span className="text-foreground/70 text-sm">({product.reviews} reviews)</span>
</div>
</div>
<p className="text-foreground/70 mb-8 text-lg">{product.description}</p>
<div className="mb-6">
<span className="text-3xl font-bold text-background-accent">${product.price.toFixed(2)}</span>
</div>
<div className="mb-8">
<h3 className="text-sm font-semibold text-foreground mb-3">Size</h3>
<div className="flex gap-3">
{["XS", "S", "M", "L", "XL", "XXL"].map((size) => (
<p className="text-foreground/80 mb-8 leading-relaxed">{product.description}</p>
{/* Size Selection */}
<div className="mb-6">
<label className="block text-foreground font-semibold mb-3">Size</label>
<div className="flex gap-3 flex-wrap">
{product.sizes.map((size: string) => (
<button
key={size}
onClick={() => setSelectedSize(size)}
className={`px-4 py-2 rounded-soft border transition-colors ${
className={`px-4 py-2 border rounded-soft transition-colors ${
selectedSize === size
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/30 text-foreground hover:border-background-accent"
: "border-accent/50 text-foreground hover:border-accent"
}`}
>
{size}
@@ -114,45 +140,71 @@ export default function ProductPage() {
</div>
</div>
<div className="mb-8">
<h3 className="text-sm font-semibold text-foreground mb-3">Quantity</h3>
<div className="flex items-center gap-3 w-fit">
<button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="px-3 py-2 border border-accent/30 rounded-soft hover:bg-accent/10 transition-colors"
>
</button>
<span className="w-12 text-center font-semibold text-foreground">{quantity}</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="px-3 py-2 border border-accent/30 rounded-soft hover:bg-accent/10 transition-colors"
>
+
</button>
{/* Color Selection */}
<div className="mb-6">
<label className="block text-foreground font-semibold mb-3">Color</label>
<div className="flex gap-3 flex-wrap">
{product.colors.map((color: string) => (
<button
key={color}
onClick={() => setSelectedColor(color)}
className={`px-4 py-2 border rounded-soft transition-colors ${
selectedColor === color
? "bg-background-accent text-primary-cta-text border-background-accent"
: "border-accent/50 text-foreground hover:border-accent"
}`}
>
{color}
</button>
))}
</div>
</div>
{/* Quantity Selection */}
<div className="mb-8">
<label className="block text-foreground font-semibold mb-3">Quantity</label>
<div className="flex items-center gap-4">
<div className="flex items-center gap-3 bg-accent/10 rounded-soft p-2 w-fit">
<button
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="p-1 hover:bg-accent/20 rounded transition-colors"
>
<span className="text-foreground"></span>
</button>
<span className="w-8 text-center text-foreground font-semibold">{quantity}</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="p-1 hover:bg-accent/20 rounded transition-colors"
>
<span className="text-foreground">+</span>
</button>
</div>
</div>
</div>
{/* Action Buttons */}
<div className="flex gap-4 mb-8">
<button className="flex-1 px-8 py-4 bg-background-accent text-primary-cta-text font-semibold rounded-soft hover:bg-primary-cta hover:text-primary-cta-text transition-colors flex items-center justify-center gap-2">
<button className="flex-1 px-6 py-3 bg-background-accent text-primary-cta-text font-semibold rounded-soft hover:bg-primary-cta hover:text-primary-cta-text transition-colors flex items-center justify-center gap-2">
<ShoppingCart size={20} />
Add to Cart
</button>
<button
onClick={() => setIsFavorited(!isFavorited)}
className={`px-6 py-4 rounded-soft border transition-colors ${
className={`px-6 py-3 border rounded-soft font-semibold transition-colors ${
isFavorited
? "bg-background-accent/20 border-background-accent"
: "border-accent/30 hover:border-background-accent"
? "bg-background-accent/10 border-background-accent text-background-accent"
: "border-accent/50 text-foreground hover:border-accent"
}`}
>
<Heart size={20} className={isFavorited ? "fill-background-accent text-background-accent" : "text-foreground"} />
<Heart size={20} fill={isFavorited ? "currentColor" : "none"} />
</button>
</div>
<div className="pt-8 border-t border-accent/20">
<h3 className="text-sm font-semibold text-foreground mb-3">Product Details</h3>
<p className="text-foreground/70 text-sm">{product.details}</p>
{/* Product Info */}
<div className="space-y-3 text-foreground/70 text-sm border-t border-accent/20 pt-6">
<p> Free shipping on orders over $150</p>
<p> 30-day return policy</p>
<p> Premium quality guaranteed</p>
</div>
</div>
</div>