Merge version_6 into main #9
154
src/app/page.tsx
154
src/app/page.tsx
@@ -11,11 +11,9 @@ import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
|
||||
import FooterSimple from '@/components/sections/footer/FooterSimple';
|
||||
import { Sparkles, Heart, Gem, Star, HelpCircle } from 'lucide-react';
|
||||
import { useState, useMemo } from 'react';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function LandingPage() {
|
||||
const [activeProductId, setActiveProductId] = useState<string | null>(null);
|
||||
const [showSprayAnimation, setShowSprayAnimation] = useState(false);
|
||||
|
||||
const products = [
|
||||
{
|
||||
id: "perfume-1", name: "Midnight Blossom", price: "$185", variant: "100ml • Floral • 3 Scent Notes", imageSrc: "http://img.b2bpic.net/free-photo/closeup-shot-beautifully-shaped-glass-bottles-filled-with-perfume_181624-28370.jpg?_wi=2", imageAlt: "Midnight Blossom Fragrance"
|
||||
@@ -38,22 +36,11 @@ export default function LandingPage() {
|
||||
];
|
||||
|
||||
const handleProductClick = (productId: string) => {
|
||||
setActiveProductId(productId);
|
||||
setShowSprayAnimation(true);
|
||||
setTimeout(() => setShowSprayAnimation(false), 2000);
|
||||
if (typeof window !== 'undefined') {
|
||||
window.location.href = `/product/${productId}`;
|
||||
}
|
||||
};
|
||||
|
||||
// Generate particle animations with stable values
|
||||
const particleAnimations = useMemo(() => {
|
||||
return Array.from({ length: 12 }).map((_, i) => ({
|
||||
id: i,
|
||||
left: (i * 8.33) % 100,
|
||||
duration: 1 + ((i * 0.7) % 1),
|
||||
delay: (i * 0.04) % 0.5,
|
||||
xOffset: ((i * 13) % 40) - 20,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="shift-hover"
|
||||
@@ -109,118 +96,27 @@ export default function LandingPage() {
|
||||
</div>
|
||||
|
||||
<div id="products" data-section="products">
|
||||
<div className="relative">
|
||||
<ProductCardFour
|
||||
products={products.map(product => ({
|
||||
...product,
|
||||
onProductClick: () => handleProductClick(product.id)
|
||||
}))}
|
||||
title="Premium Fragrance Collection"
|
||||
description="Sourced from master perfumers worldwide, authenticity guaranteed. Handpicked luxury perfumes and cosmetics for the discerning connoisseur. Click to explore interactive product animations"
|
||||
tag="Featured Selection"
|
||||
tagIcon={Heart}
|
||||
tagAnimation="slide-up"
|
||||
buttons={[
|
||||
{ text: "View All Products", href: "#" },
|
||||
{ text: "Shop Collection", href: "#" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
gridVariant="uniform-all-items-equal"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
carouselMode="buttons"
|
||||
/>
|
||||
|
||||
{activeProductId && showSprayAnimation && (
|
||||
<div className="fixed inset-0 pointer-events-none z-50 flex items-center justify-center">
|
||||
<div className="relative w-96 h-96">
|
||||
{/* Product rotates leftward */}
|
||||
<div className="absolute inset-0 animate-spin-slow" style={{
|
||||
animationDuration: '2s',
|
||||
animationDirection: 'reverse',
|
||||
transformOrigin: 'center',
|
||||
}}>
|
||||
<img
|
||||
src={products.find(p => p.id === activeProductId)?.imageSrc}
|
||||
alt="Product"
|
||||
className="w-full h-full object-cover rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Spray particles animation */}
|
||||
<div className="absolute inset-0 overflow-hidden rounded-lg">
|
||||
{particleAnimations.map((particle) => (
|
||||
<div
|
||||
key={particle.id}
|
||||
className="absolute w-2 h-2 bg-gradient-to-b from-white to-transparent rounded-full"
|
||||
style={{
|
||||
left: `${particle.left}%`,
|
||||
top: `-10px`,
|
||||
animation: `fall ${particle.duration}s ease-out forwards`,
|
||||
animationDelay: `${particle.delay}s`,
|
||||
opacity: 0.7,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Product information reveal overlay */}
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent rounded-lg flex flex-col justify-end p-6 text-white"
|
||||
style={{
|
||||
animation: 'fadeIn 1.2s ease-in forwards',
|
||||
animationDelay: '0.5s',
|
||||
}}
|
||||
>
|
||||
<div className="opacity-0 animate-fadeInUp" style={{ animationDelay: '0.8s' }}>
|
||||
<h3 className="text-2xl font-bold mb-2">
|
||||
{products.find(p => p.id === activeProductId)?.name}
|
||||
</h3>
|
||||
<p className="text-sm mb-2">
|
||||
{products.find(p => p.id === activeProductId)?.variant}
|
||||
</p>
|
||||
<p className="text-xl font-semibold">
|
||||
{products.find(p => p.id === activeProductId)?.price}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
@keyframes spin-slow {
|
||||
from { transform: rotateY(0deg); }
|
||||
to { transform: rotateY(-180deg); }
|
||||
}
|
||||
@keyframes fall {
|
||||
to {
|
||||
transform: translateY(100px) translateX(0px);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.animate-spin-slow {
|
||||
animation: spin-slow 2s reverse;
|
||||
}
|
||||
.animate-fadeInUp {
|
||||
animation: fadeInUp 1s ease-out forwards;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ProductCardFour
|
||||
products={products.map(product => ({
|
||||
...product,
|
||||
onProductClick: () => handleProductClick(product.id)
|
||||
}))}
|
||||
title="Premium Fragrance Collection"
|
||||
description="Sourced from master perfumers worldwide, authenticity guaranteed. Handpicked luxury perfumes and cosmetics for the discerning connoisseur. Click to explore interactive product animations"
|
||||
tag="Featured Selection"
|
||||
tagIcon={Heart}
|
||||
tagAnimation="slide-up"
|
||||
buttons={[
|
||||
{ text: "View All Products", href: "#" },
|
||||
{ text: "Shop Collection", href: "#" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
gridVariant="uniform-all-items-equal"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
carouselMode="buttons"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="about" data-section="about">
|
||||
|
||||
351
src/app/product/[id]/page.tsx
Normal file
351
src/app/product/[id]/page.tsx
Normal file
@@ -0,0 +1,351 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
|
||||
import FooterSimple from '@/components/sections/footer/FooterSimple';
|
||||
import Link from 'next/link';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useEffect, useState, useMemo } from 'react';
|
||||
|
||||
const products = [
|
||||
{
|
||||
id: "perfume-1", name: "Midnight Blossom", price: "$185", variant: "100ml • Floral • 3 Scent Notes", imageSrc: "http://img.b2bpic.net/free-photo/closeup-shot-beautifully-shaped-glass-bottles-filled-with-perfume_181624-28370.jpg?_wi=2", imageAlt: "Midnight Blossom Fragrance", description: "A captivating floral fragrance that combines the essence of midnight jasmine with subtle notes of moonflower. This exquisite blend creates an aura of mystery and elegance, perfect for evening occasions."
|
||||
},
|
||||
{
|
||||
id: "perfume-2", name: "Crystal Noir", price: "$210", variant: "100ml • Oriental • Premium Edition", imageSrc: "http://img.b2bpic.net/free-photo/close-up-variety-cosmetic-products-desk-isolated_574295-5284.jpg?_wi=2", imageAlt: "Crystal Noir Fragrance", description: "A luxurious oriental fragrance with deep amber and exotic spices. The premium edition features notes of oud, vanilla, and sandalwood, creating an intoxicating and sophisticated scent."
|
||||
},
|
||||
{
|
||||
id: "perfume-3", name: "Amber Essence", price: "$165", variant: "75ml • Woody • Signature Collection", imageSrc: "http://img.b2bpic.net/free-photo/ecofriendly-beauty-product_23-2150669115.jpg?_wi=2", imageAlt: "Amber Essence Fragrance", description: "A warm and woody composition from our signature collection. Featuring cedarwood and amber with hints of vanilla, this fragrance is timeless, versatile, and perfect for everyday wear."
|
||||
},
|
||||
{
|
||||
id: "perfume-4", name: "Rose Garden", price: "$195", variant: "100ml • Fruity Floral • Limited Release", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=3", imageAlt: "Rose Garden Fragrance", description: "A beautiful fruity floral from our limited release collection. Fresh rose petals blend with juicy berry notes, creating a romantic and vibrant fragrance for spring and summer."
|
||||
},
|
||||
{
|
||||
id: "perfume-5", name: "Ocean Wave", price: "$175", variant: "100ml • Fresh Citrus • Summer Collection", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=4", imageAlt: "Ocean Wave Fragrance", description: "A refreshing citrus fragrance inspired by ocean breezes. With notes of lemon, bergamot, and sea salt, this summer collection favorite brings the essence of coastal freshness to your day."
|
||||
},
|
||||
{
|
||||
id: "perfume-6", name: "Vanilla Luxe", price: "$200", variant: "100ml • Gourmand • Exclusive Blend", imageSrc: "http://img.b2bpic.net/free-photo/elegant-vegan-alcohol-arrangement_23-2149337695.jpg?_wi=2", imageAlt: "Vanilla Luxe Fragrance", description: "An exclusive gourmand blend with creamy vanilla and caramel notes. Perfect for those who love indulgent fragrances with a touch of sweetness and sophistication."
|
||||
}
|
||||
];
|
||||
|
||||
export default function ProductDetailPage() {
|
||||
const params = useParams();
|
||||
const productId = params?.id as string;
|
||||
const [showAnimation, setShowAnimation] = useState(true);
|
||||
const [infoRevealed, setInfoRevealed] = useState(false);
|
||||
const [product, setProduct] = useState<typeof products[0] | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const foundProduct = products.find(p => p.id === productId);
|
||||
if (foundProduct) {
|
||||
setProduct(foundProduct);
|
||||
}
|
||||
}, [productId]);
|
||||
|
||||
const particleAnimations = useMemo(() => {
|
||||
return Array.from({ length: 12 }).map((_, i) => ({
|
||||
id: i,
|
||||
left: (i * 8.33) % 100,
|
||||
duration: 1 + ((i * 0.7) % 1),
|
||||
delay: (i * 0.04) % 0.5,
|
||||
xOffset: ((i * 13) % 40) - 20,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const rotationDuration = 2000;
|
||||
const revealDelay = 1200;
|
||||
const sprayDuration = 2000;
|
||||
|
||||
const animationTimer = setTimeout(() => {
|
||||
setShowAnimation(false);
|
||||
}, sprayDuration + rotationDuration);
|
||||
|
||||
const infoTimer = setTimeout(() => {
|
||||
setInfoRevealed(true);
|
||||
}, revealDelay + rotationDuration);
|
||||
|
||||
return () => {
|
||||
clearTimeout(animationTimer);
|
||||
clearTimeout(infoTimer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!product) {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="shift-hover"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="noiseDiagonalGradient"
|
||||
cardStyle="soft-shadow"
|
||||
primaryButtonStyle="flat"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="medium"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleFullscreen
|
||||
navItems={[
|
||||
{ name: "Shop", id: "products" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "Reviews", id: "testimonials" },
|
||||
{ name: "FAQ", id: "faq" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
brandName="Essence & Aura"
|
||||
bottomLeftText="Luxury Fragrances"
|
||||
bottomRightText="hello@essenceaura.com"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-center min-h-[60vh]">
|
||||
<p className="text-xl">Product not found. <Link href="/" className="text-blue-600 underline">Return home</Link></p>
|
||||
</div>
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterSimple
|
||||
columns={[
|
||||
{
|
||||
title: "Navigate", items: [
|
||||
{ label: "Home", href: "/" },
|
||||
{ label: "Shop", href: "#products" }
|
||||
]
|
||||
}
|
||||
]}
|
||||
bottomLeftText="© 2025 Essence & Aura. All rights reserved."
|
||||
bottomRightText="Crafted with luxury and passion"
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="shift-hover"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="pill"
|
||||
contentWidth="small"
|
||||
sizing="mediumLargeSizeLargeTitles"
|
||||
background="noiseDiagonalGradient"
|
||||
cardStyle="soft-shadow"
|
||||
primaryButtonStyle="flat"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="medium"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleFullscreen
|
||||
navItems={[
|
||||
{ name: "Shop", id: "products" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "Reviews", id: "testimonials" },
|
||||
{ name: "FAQ", id: "faq" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
brandName="Essence & Aura"
|
||||
bottomLeftText="Luxury Fragrances"
|
||||
bottomRightText="hello@essenceaura.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative pt-32 pb-20 px-6 md:px-12 min-h-screen flex items-center justify-center">
|
||||
{showAnimation && (
|
||||
<div className="absolute inset-0 pointer-events-none z-50 flex items-center justify-center pt-32">
|
||||
<div className="relative w-80 h-80 md:w-96 md:h-96">
|
||||
{/* Product rotates leftward */}
|
||||
<div
|
||||
className="absolute inset-0 will-change-transform"
|
||||
style={{
|
||||
animation: `rotateLeftThenRight 3s ease-in-out forwards`,
|
||||
transformOrigin: 'center',
|
||||
transformStyle: 'preserve-3d',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={product.imageSrc}
|
||||
alt={product.imageAlt}
|
||||
className="w-full h-full object-cover rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Spray particles animation */}
|
||||
<div className="absolute inset-0 overflow-hidden rounded-lg">
|
||||
{particleAnimations.map((particle) => (
|
||||
<div
|
||||
key={particle.id}
|
||||
className="absolute w-2 h-2 bg-gradient-to-b from-white to-transparent rounded-full pointer-events-none"
|
||||
style={{
|
||||
left: `${particle.left}%`,
|
||||
top: `-10px`,
|
||||
animation: `fall ${particle.duration}s ease-out forwards`,
|
||||
animationDelay: `${0.8 + particle.delay}s`,
|
||||
opacity: 0.7,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Product details section */}
|
||||
<div className="relative w-full max-w-2xl">
|
||||
{infoRevealed && (
|
||||
<div
|
||||
className="space-y-6 animate-fadeInUp"
|
||||
style={{
|
||||
animation: 'fadeInUp 0.8s ease-out forwards',
|
||||
}}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<h1 className="text-5xl md:text-6xl font-bold text-foreground">
|
||||
{product.name}
|
||||
</h1>
|
||||
<p className="text-xl text-foreground/80">
|
||||
{product.variant}
|
||||
</p>
|
||||
<p className="text-lg text-foreground/70 leading-relaxed">
|
||||
{product.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<p className="text-3xl font-bold text-primary-cta">
|
||||
{product.price}
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<button className="px-8 py-3 bg-primary-cta text-primary-cta-text rounded-full font-semibold hover:opacity-90 transition">
|
||||
Add to Cart
|
||||
</button>
|
||||
<Link
|
||||
href="/"
|
||||
className="px-8 py-3 bg-secondary-cta text-secondary-cta-text rounded-full font-semibold hover:opacity-90 transition text-center"
|
||||
>
|
||||
Continue Shopping
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!infoRevealed && !showAnimation && (
|
||||
<div
|
||||
className="space-y-6 animate-fadeInUp"
|
||||
style={{
|
||||
animation: 'fadeInUp 0.8s ease-out forwards',
|
||||
}}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<h1 className="text-5xl md:text-6xl font-bold text-foreground">
|
||||
{product.name}
|
||||
</h1>
|
||||
<p className="text-xl text-foreground/80">
|
||||
{product.variant}
|
||||
</p>
|
||||
<p className="text-lg text-foreground/70 leading-relaxed">
|
||||
{product.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<p className="text-3xl font-bold text-primary-cta">
|
||||
{product.price}
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<button className="px-8 py-3 bg-primary-cta text-primary-cta-text rounded-full font-semibold hover:opacity-90 transition">
|
||||
Add to Cart
|
||||
</button>
|
||||
<Link
|
||||
href="/"
|
||||
className="px-8 py-3 bg-secondary-cta text-secondary-cta-text rounded-full font-semibold hover:opacity-90 transition text-center"
|
||||
>
|
||||
Continue Shopping
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterSimple
|
||||
columns={[
|
||||
{
|
||||
title: "Navigate", items: [
|
||||
{ label: "Home", href: "/" },
|
||||
{ label: "Shop", href: "/#products" },
|
||||
{ label: "About", href: "/#about" },
|
||||
{ label: "Reviews", href: "/#testimonials" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Support", items: [
|
||||
{ label: "FAQ", href: "/#faq" },
|
||||
{ label: "Contact Us", href: "/#contact" },
|
||||
{ label: "Shipping Info", href: "#" },
|
||||
{ label: "Returns", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "/#about" },
|
||||
{ label: "Our Story", href: "/#about" },
|
||||
{ label: "Careers", href: "#" },
|
||||
{ label: "Blog", href: "#" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Legal", items: [
|
||||
{ label: "Privacy Policy", href: "#" },
|
||||
{ label: "Terms of Service", href: "#" },
|
||||
{ label: "Cookie Policy", href: "#" }
|
||||
]
|
||||
}
|
||||
]}
|
||||
bottomLeftText="© 2025 Essence & Aura. All rights reserved."
|
||||
bottomRightText="Crafted with luxury and passion"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
@keyframes rotateLeftThenRight {
|
||||
0% {
|
||||
transform: perspective(1000px) rotateY(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
transform: perspective(1000px) rotateY(-90deg);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: perspective(1000px) rotateY(90deg);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fall {
|
||||
to {
|
||||
transform: translateY(100px) translateX(0px);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fadeInUp {
|
||||
animation: fadeInUp 0.8s ease-out forwards;
|
||||
}
|
||||
`}</style>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user