Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f4993e0493 | |||
| 6d46dd6307 | |||
| 33c9fc41a6 | |||
| d2333073d7 | |||
| 0c0de562eb | |||
| fb8e149605 |
237
src/app/cart/page.tsx
Normal file
237
src/app/cart/page.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import TestimonialCardFifteen from '@/components/sections/testimonial/Testimonia
|
|||||||
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
|
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
|
||||||
import ContactCenter from '@/components/sections/contact/ContactCenter';
|
import ContactCenter from '@/components/sections/contact/ContactCenter';
|
||||||
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
|
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
|
||||||
import { Sparkles, Leaf, Droplets, Shield, Mail } from "lucide-react";
|
import { Sparkles, Leaf, Droplets, Shield, Mail, ShoppingCart } from "lucide-react";
|
||||||
|
|
||||||
export default function LandingPage() {
|
export default function LandingPage() {
|
||||||
return (
|
return (
|
||||||
@@ -92,6 +92,7 @@ export default function LandingPage() {
|
|||||||
useInvertedBackground={true}
|
useInvertedBackground={true}
|
||||||
tagAnimation="slide-up"
|
tagAnimation="slide-up"
|
||||||
buttonAnimation="slide-up"
|
buttonAnimation="slide-up"
|
||||||
|
buttons={[{ text: "View Details", href: "/product-detail" }]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -203,7 +204,8 @@ export default function LandingPage() {
|
|||||||
{ label: "Contact", href: "#contact" },
|
{ label: "Contact", href: "#contact" },
|
||||||
{ label: "FAQ", href: "#faq" },
|
{ label: "FAQ", href: "#faq" },
|
||||||
{ label: "Shipping", href: "#" },
|
{ label: "Shipping", href: "#" },
|
||||||
{ label: "Returns", href: "#" }
|
{ label: "Returns", href: "#" },
|
||||||
|
{ label: "Track Order", href: "#" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -220,4 +222,4 @@ export default function LandingPage() {
|
|||||||
</div>
|
</div>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
136
src/app/product-detail/page.tsx
Normal file
136
src/app/product-detail/page.tsx
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
|
||||||
|
import ProductDetailCard from '@/components/ecommerce/productDetail/ProductDetailCard';
|
||||||
|
import ContactCenter from '@/components/sections/contact/ContactCenter';
|
||||||
|
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
|
||||||
|
import { Mail, ArrowLeft } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function ProductDetailPage() {
|
||||||
|
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 id="product-detail" data-section="product-detail" className="pt-20">
|
||||||
|
<div className="mb-8 px-4">
|
||||||
|
<Link href="/" className="inline-flex items-center gap-2 text-foreground hover:opacity-70 transition-opacity">
|
||||||
|
<ArrowLeft className="w-4 h-4" />
|
||||||
|
<span>Back to Products</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<ProductDetailCard
|
||||||
|
layout="page"
|
||||||
|
name="Radiant Hydration Moisturizer"
|
||||||
|
price="$58.00"
|
||||||
|
rating={4.5}
|
||||||
|
description="Discover luxurious hydration with our Radiant Hydration Moisturizer. Formulated with organic botanicals and advanced moisture-locking technology, this lightweight yet nourishing cream provides 24-hour hydration while promoting a visibly brighter, more luminous complexion. Perfect for all skin types, especially those seeking radiant, glowing skin."
|
||||||
|
images={[
|
||||||
|
{ src: "http://img.b2bpic.net/free-vector/cosmetics-products-realistic-composition-poster_1284-18210.jpg", alt: "Radiant Hydration Moisturizer - Front" },
|
||||||
|
{ src: "http://img.b2bpic.net/free-photo/top-view-gua-sha-face-products_23-2149401501.jpg", alt: "Radiant Hydration Moisturizer - Application" },
|
||||||
|
{ src: "http://img.b2bpic.net/free-photo/front-view-argan-product-composition_23-2148955787.jpg", alt: "Radiant Hydration Moisturizer - Ingredients" }
|
||||||
|
]}
|
||||||
|
variants={[
|
||||||
|
{
|
||||||
|
label: "Size", options: ["50ml", "100ml", "200ml"],
|
||||||
|
selected: "50ml", onChange: (value) => console.log("Size selected:", value)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Formula Type", options: ["Lightweight Gel", "Rich Cream", "Night Intensive"],
|
||||||
|
selected: "Lightweight Gel", onChange: (value) => console.log("Formula selected:", value)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
quantity={{
|
||||||
|
label: "Quantity", options: ["1", "2", "3", "4", "5"],
|
||||||
|
selected: "1", onChange: (value) => console.log("Quantity selected:", value)
|
||||||
|
}}
|
||||||
|
buttons={[
|
||||||
|
{ text: "Add To Cart", onClick: () => alert("Product added to cart!") },
|
||||||
|
{ text: "Buy Now", href: "#" }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="contact" data-section="contact">
|
||||||
|
<ContactCenter
|
||||||
|
tag="Stay Glowing"
|
||||||
|
tagIcon={Mail}
|
||||||
|
title="Join Our Beauty Community"
|
||||||
|
description="Subscribe to receive exclusive skincare tips, new product launches, and special discounts delivered straight to your inbox."
|
||||||
|
background={{ variant: "sparkles-gradient" }}
|
||||||
|
useInvertedBackground={false}
|
||||||
|
inputPlaceholder="Enter your email"
|
||||||
|
buttonText="Subscribe"
|
||||||
|
termsText="We respect your privacy. Unsubscribe anytime. By subscribing, you agree to our newsletter terms."
|
||||||
|
tagAnimation="slide-up"
|
||||||
|
/>
|
||||||
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
246
src/app/shop/page.tsx
Normal file
246
src/app/shop/page.tsx
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||||
|
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
|
||||||
|
import ProductCardTwo from '@/components/sections/product/ProductCardTwo';
|
||||||
|
import ContactCenter from '@/components/sections/contact/ContactCenter';
|
||||||
|
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
|
||||||
|
import { Mail, Search } from "lucide-react";
|
||||||
|
|
||||||
|
const allProducts = [
|
||||||
|
{
|
||||||
|
id: "1", brand: "Pure Glow", name: "Radiant Hydration Moisturizer", price: "$58.00", rating: 5,
|
||||||
|
reviewCount: "328", imageSrc: "http://img.b2bpic.net/free-vector/cosmetics-products-realistic-composition-poster_1284-18210.jpg", imageAlt: "Radiant Hydration Moisturizer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2", brand: "Pure Glow", name: "Luminous Glow Serum", price: "$72.00", rating: 5,
|
||||||
|
reviewCount: "412", imageSrc: "http://img.b2bpic.net/free-photo/front-view-argan-product-composition_23-2148955787.jpg", imageAlt: "Luminous Glow Serum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3", brand: "Pure Glow", name: "Purifying Wellness Mask", price: "$48.00", rating: 4,
|
||||||
|
reviewCount: "267", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-body-butter-pink-cloth_23-2148305543.jpg", imageAlt: "Purifying Wellness Mask"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4", brand: "Pure Glow", name: "Gentle Cleansing Oil", price: "$52.00", rating: 5,
|
||||||
|
reviewCount: "189", imageSrc: "http://img.b2bpic.net/free-photo/top-view-gua-sha-face-products_23-2149401501.jpg", imageAlt: "Gentle Cleansing Oil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "5", brand: "Pure Glow", name: "Anti-Aging Eye Serum", price: "$65.00", rating: 4,
|
||||||
|
reviewCount: "294", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-levender-body-butter-plain-background_23-2148305506.jpg", imageAlt: "Anti-Aging Eye Serum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "6", brand: "Pure Glow", name: "Nourishing Night Cream", price: "$68.00", rating: 5,
|
||||||
|
reviewCount: "356", imageSrc: "http://img.b2bpic.net/free-vector/cosmetics-products-realistic-composition-poster_1284-18210.jpg", imageAlt: "Nourishing Night Cream"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "7", brand: "Pure Glow", name: "Brightening Vitamin C Powder", price: "$55.00", rating: 4,
|
||||||
|
reviewCount: "221", imageSrc: "http://img.b2bpic.net/free-photo/front-view-argan-product-composition_23-2148955787.jpg", imageAlt: "Brightening Vitamin C Powder"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "8", brand: "Pure Glow", name: "Hydrating Face Mist", price: "$42.00", rating: 5,
|
||||||
|
reviewCount: "445", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-body-butter-pink-cloth_23-2148305543.jpg", imageAlt: "Hydrating Face Mist"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ShopPage() {
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [selectedFilter, setSelectedFilter] = useState("all");
|
||||||
|
const [favoriteItems, setFavoriteItems] = useState<Set<string>>(new Set());
|
||||||
|
|
||||||
|
const filters = [
|
||||||
|
{ id: "all", label: "All Products" },
|
||||||
|
{ id: "serums", label: "Serums" },
|
||||||
|
{ id: "moisturizers", label: "Moisturizers" },
|
||||||
|
{ id: "masks", label: "Masks" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const filterProducts = () => {
|
||||||
|
let filtered = allProducts;
|
||||||
|
|
||||||
|
// Apply search filter
|
||||||
|
if (searchTerm) {
|
||||||
|
filtered = filtered.filter(product =>
|
||||||
|
product.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
product.brand.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply category filter
|
||||||
|
if (selectedFilter !== "all") {
|
||||||
|
filtered = filtered.filter(product => {
|
||||||
|
const name = product.name.toLowerCase();
|
||||||
|
if (selectedFilter === "serums") return name.includes("serum");
|
||||||
|
if (selectedFilter === "moisturizers") return name.includes("moisturizer") || name.includes("cream");
|
||||||
|
if (selectedFilter === "masks") return name.includes("mask");
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleFavorite = (productId: string) => {
|
||||||
|
const newFavorites = new Set(favoriteItems);
|
||||||
|
if (newFavorites.has(productId)) {
|
||||||
|
newFavorites.delete(productId);
|
||||||
|
} else {
|
||||||
|
newFavorites.add(productId);
|
||||||
|
}
|
||||||
|
setFavoriteItems(newFavorites);
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredProducts = filterProducts();
|
||||||
|
const displayProducts = filteredProducts.map(product => ({
|
||||||
|
...product,
|
||||||
|
isFavorited: favoriteItems.has(product.id),
|
||||||
|
onFavorite: () => toggleFavorite(product.id)
|
||||||
|
}));
|
||||||
|
|
||||||
|
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: "/" },
|
||||||
|
{ name: "Products", id: "/shop" },
|
||||||
|
{ name: "About", id: "about" },
|
||||||
|
{ name: "Benefits", id: "feature" },
|
||||||
|
{ name: "Contact", id: "contact" }
|
||||||
|
]}
|
||||||
|
button={{ text: "Shop Now", href: "/shop" }}
|
||||||
|
brandName="Pure Glow"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="shop" data-section="shop" className="py-20">
|
||||||
|
<div className="max-w-7xl mx-auto px-4">
|
||||||
|
{/* Shop Header */}
|
||||||
|
<div className="mb-12 text-center">
|
||||||
|
<h1 className="text-4xl md:text-5xl font-extrabold mb-4">Our Shop</h1>
|
||||||
|
<p className="text-lg md:text-xl opacity-75 max-w-2xl mx-auto mb-8">
|
||||||
|
Browse our complete collection of premium skincare products
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Search Bar */}
|
||||||
|
<div className="flex items-center max-w-md mx-auto mb-8">
|
||||||
|
<div className="relative w-full">
|
||||||
|
<Search className="absolute left-3 top-3 w-5 h-5 opacity-50" />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search products..."
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
className="w-full pl-10 pr-4 py-2 border border-current border-opacity-20 rounded-lg focus:outline-none focus:ring-2 focus:ring-current focus:ring-opacity-50"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filter Buttons */}
|
||||||
|
<div className="flex flex-wrap justify-center gap-3">
|
||||||
|
{filters.map(filter => (
|
||||||
|
<button
|
||||||
|
key={filter.id}
|
||||||
|
onClick={() => setSelectedFilter(filter.id)}
|
||||||
|
className={`px-6 py-2 rounded-lg font-medium transition-all ${
|
||||||
|
selectedFilter === filter.id
|
||||||
|
? "bg-current text-background"
|
||||||
|
: "bg-current bg-opacity-10 hover:bg-opacity-20"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{filter.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Results Count */}
|
||||||
|
<p className="text-center text-sm opacity-75 mb-8">
|
||||||
|
Showing {displayProducts.length} product{displayProducts.length !== 1 ? "s" : ""}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="product" data-section="product">
|
||||||
|
<ProductCardTwo
|
||||||
|
products={displayProducts}
|
||||||
|
title="Featured Electronics"
|
||||||
|
description="Discover our curated selection of premium electronics and tech products"
|
||||||
|
gridVariant="four-items-2x2-equal-grid"
|
||||||
|
animationType="slide-up"
|
||||||
|
textboxLayout="default"
|
||||||
|
useInvertedBackground={true}
|
||||||
|
tagAnimation="slide-up"
|
||||||
|
buttonAnimation="slide-up"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="contact" data-section="contact">
|
||||||
|
<ContactCenter
|
||||||
|
tag="Stay Updated"
|
||||||
|
tagIcon={Mail}
|
||||||
|
title="Join Our Beauty Community"
|
||||||
|
description="Subscribe to receive exclusive skincare tips, new product launches, and special discounts delivered straight to your inbox."
|
||||||
|
background={{ variant: "sparkles-gradient" }}
|
||||||
|
useInvertedBackground={false}
|
||||||
|
inputPlaceholder="Enter your email"
|
||||||
|
buttonText="Subscribe"
|
||||||
|
termsText="We respect your privacy. Unsubscribe anytime. By subscribing, you agree to our newsletter terms."
|
||||||
|
tagAnimation="slide-up"
|
||||||
|
/>
|
||||||
|
</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: "/" },
|
||||||
|
{ 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: "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,36 +8,34 @@ interface SvgTextLogoProps {
|
|||||||
const SvgTextLogo: React.FC<SvgTextLogoProps> = ({ text, className = '' }) => {
|
const SvgTextLogo: React.FC<SvgTextLogoProps> = ({ text, className = '' }) => {
|
||||||
const textLength = text.length;
|
const textLength = text.length;
|
||||||
const charWidth = 60;
|
const charWidth = 60;
|
||||||
const width = Math.max(300, textLength * charWidth);
|
const width = textLength * charWidth + 40;
|
||||||
const height = 120;
|
const height = 120;
|
||||||
const fontSize = 80;
|
|
||||||
const x = width / 2;
|
|
||||||
const y = height / 2;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
viewBox={`0 0 ${width} ${height}`}
|
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
|
viewBox={`0 0 ${width} ${height}`}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
className={className}
|
className={className}
|
||||||
aria-label={text}
|
|
||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
<linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
<stop offset="0%" style={{ stopColor: 'rgb(59, 130, 246)', stopOpacity: 1 }} />
|
<stop offset="0%" stopColor="#ff6b6b" />
|
||||||
<stop offset="100%" style={{ stopColor: 'rgb(139, 92, 246)', stopOpacity: 1 }} />
|
<stop offset="50%" stopColor="#4ecdc4" />
|
||||||
|
<stop offset="100%" stopColor="#45b7d1" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<text
|
<text
|
||||||
x={x}
|
x={width / 2}
|
||||||
y={y}
|
y={height / 2}
|
||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
dominantBaseline="middle"
|
dominantBaseline="middle"
|
||||||
fontSize={fontSize}
|
fontSize="48"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
fill="url(#textGradient)"
|
fill="url(#textGradient)"
|
||||||
fontFamily="system-ui, -apple-system, sans-serif"
|
fontFamily="Arial, sans-serif"
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
</text>
|
</text>
|
||||||
@@ -45,4 +43,4 @@ const SvgTextLogo: React.FC<SvgTextLogoProps> = ({ text, className = '' }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SvgTextLogo;
|
export default SvgTextLogo;
|
||||||
Reference in New Issue
Block a user