Add src/app/cart/page.tsx

This commit is contained in:
2026-03-12 06:04:14 +00:00
parent 4c779fff3d
commit fb8e149605

237
src/app/cart/page.tsx Normal file
View File

@@ -0,0 +1,237 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { Mail, Trash2, Plus, Minus } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
image: string;
}
export default function CartPage() {
const [cartItems, setCartItems] = useState<CartItem[]>([
{
id: "1", name: "Radiant Hydration Moisturizer", price: 58,
quantity: 1,
image: "http://img.b2bpic.net/free-vector/cosmetics-products-realistic-composition-poster_1284-18210.jpg"
},
{
id: "2", name: "Luminous Glow Serum", price: 72,
quantity: 2,
image: "http://img.b2bpic.net/free-photo/front-view-argan-product-composition_23-2148955787.jpg"
}
]);
const updateQuantity = (id: string, newQuantity: number) => {
if (newQuantity <= 0) {
removeItem(id);
} else {
setCartItems(cartItems.map(item =>
item.id === id ? { ...item, quantity: newQuantity } : item
));
}
};
const removeItem = (id: string) => {
setCartItems(cartItems.filter(item => item.id !== id));
};
const subtotal = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
const tax = subtotal * 0.1;
const shipping = subtotal > 100 ? 0 : 10;
const total = subtotal + tax + shipping;
return (
<ThemeProvider
defaultButtonVariant="hover-bubble"
defaultTextAnimation="reveal-blur"
borderRadius="rounded"
contentWidth="small"
sizing="largeSmallSizeLargeTitles"
background="aurora"
cardStyle="gradient-bordered"
primaryButtonStyle="double-inset"
secondaryButtonStyle="solid"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleCentered
navItems={[
{ name: "Home", id: "home" },
{ name: "Products", id: "product" },
{ name: "About", id: "about" },
{ name: "Benefits", id: "feature" },
{ name: "Contact", id: "contact" }
]}
button={{ text: "Shop Now", href: "#" }}
brandName="Pure Glow"
/>
</div>
<div className="min-h-screen pt-32 pb-20">
<div className="max-w-6xl mx-auto px-4">
<div className="mb-8">
<h1 className="text-5xl font-bold mb-4">Shopping Cart</h1>
<p className="text-lg text-foreground/70">{cartItems.length} items in your cart</p>
</div>
{cartItems.length === 0 ? (
<div className="text-center py-20">
<p className="text-xl text-foreground/70 mb-8">Your cart is empty</p>
<Link
href="/"
className="inline-block px-8 py-3 bg-primary-cta text-background rounded-lg font-semibold hover:opacity-90 transition-opacity"
>
Continue Shopping
</Link>
</div>
) : (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div className="lg:col-span-2">
<div className="space-y-4">
{cartItems.map((item) => (
<div
key={item.id}
className="flex gap-4 p-4 rounded-lg border border-card bg-card/50 backdrop-blur"
>
<img
src={item.image}
alt={item.name}
className="w-24 h-24 object-cover rounded-lg"
/>
<div className="flex-1">
<h3 className="font-semibold text-lg mb-1">{item.name}</h3>
<p className="text-primary-cta font-semibold mb-3">${item.price.toFixed(2)}</p>
<div className="flex items-center gap-2">
<button
onClick={() => updateQuantity(item.id, item.quantity - 1)}
className="p-1 hover:bg-background/50 rounded transition-colors"
aria-label="Decrease quantity"
>
<Minus className="w-4 h-4" />
</button>
<input
type="number"
value={item.quantity}
onChange={(e) => updateQuantity(item.id, parseInt(e.target.value) || 1)}
className="w-12 text-center border border-background-accent rounded px-2 py-1"
min="1"
/>
<button
onClick={() => updateQuantity(item.id, item.quantity + 1)}
className="p-1 hover:bg-background/50 rounded transition-colors"
aria-label="Increase quantity"
>
<Plus className="w-4 h-4" />
</button>
</div>
</div>
<div className="text-right">
<p className="font-semibold text-lg mb-4">${(item.price * item.quantity).toFixed(2)}</p>
<button
onClick={() => removeItem(item.id)}
className="p-2 hover:bg-red-500/10 rounded transition-colors text-red-500"
aria-label="Remove item"
>
<Trash2 className="w-5 h-5" />
</button>
</div>
</div>
))}
</div>
</div>
<div className="lg:col-span-1">
<div className="p-6 rounded-lg border border-card bg-card/50 backdrop-blur sticky top-32">
<h2 className="text-2xl font-bold mb-6">Order Summary</h2>
<div className="space-y-3 mb-6 pb-6 border-b border-background-accent">
<div className="flex justify-between">
<span className="text-foreground/70">Subtotal</span>
<span>${subtotal.toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/70">Tax (10%)</span>
<span>${tax.toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span className="text-foreground/70">Shipping</span>
<span>{shipping === 0 ? "FREE" : `$${shipping.toFixed(2)}`}</span>
</div>
</div>
<div className="flex justify-between items-center mb-6 text-lg font-bold">
<span>Total</span>
<span>${total.toFixed(2)}</span>
</div>
<button
className="w-full px-6 py-3 bg-primary-cta text-background rounded-lg font-semibold hover:opacity-90 transition-opacity mb-3"
onClick={() => alert("Proceeding to checkout...")}
>
Proceed to Checkout
</button>
<Link
href="/"
className="block w-full px-6 py-3 border border-secondary-cta text-secondary-cta rounded-lg font-semibold text-center hover:bg-secondary-cta/10 transition-colors"
>
Continue Shopping
</Link>
{shipping === 0 && subtotal > 0 && (
<p className="text-sm text-accent text-center mt-3"> Free shipping on orders over $100</p>
)}
</div>
</div>
</div>
)}
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseCard
logoText="Pure Glow"
columns={[
{
title: "Products", items: [
{ label: "Moisturizers", href: "#" },
{ label: "Serums", href: "#" },
{ label: "Masks", href: "#" },
{ label: "Cleansers", href: "#" }
]
},
{
title: "Company", items: [
{ label: "About Us", href: "#about" },
{ label: "Our Story", href: "#" },
{ label: "Careers", href: "#" },
{ label: "Blog", href: "#" }
]
},
{
title: "Support", items: [
{ label: "Contact", href: "#contact" },
{ label: "FAQ", href: "#faq" },
{ label: "Shipping", href: "#" },
{ label: "Returns", href: "#" },
{ label: "Track Order", href: "#" }
]
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Sustainability", href: "#" },
{ label: "Accessibility", href: "#" }
]
}
]}
copyrightText="© 2025 Pure Glow. All rights reserved. Crafted with love for your skin."
/>
</div>
</ThemeProvider>
);
}