Merge version_6 into main #11

Merged
bender merged 3 commits from version_6 into main 2026-03-03 11:35:56 +00:00
3 changed files with 208 additions and 247 deletions

View File

@@ -21,11 +21,9 @@ const sourceSans3 = Source_Sans_3({
export const metadata: Metadata = {
title: "Essence & Aura | Premium Luxury Perfumes & Cosmetics", description: "Discover curated luxury fragrances with interactive animated product experiences. Premium perfumes and cosmetics for the discerning connoisseur.", keywords: "luxury perfume, fragrance, cosmetics, premium scent, perfume shop, interactive shopping", openGraph: {
title: "Essence & Aura | Discover Your Signature Scent", description: "Experience premium luxury fragrances with immersive interactive animations", type: "website", siteName: "Essence & Aura"
},
title: "Essence & Aura | Discover Your Signature Scent", description: "Experience premium luxury fragrances with immersive interactive animations", type: "website", siteName: "Essence & Aura"},
twitter: {
card: "summary_large_image", title: "Essence & Aura | Premium Fragrances", description: "Luxury perfumes with interactive product experiences"
},
card: "summary_large_image", title: "Essence & Aura | Premium Fragrances", description: "Luxury perfumes with interactive product experiences"},
};
export default function RootLayout({
@@ -1412,4 +1410,4 @@ export default function RootLayout({
</ServiceWrapper>
</html>
);
}
}

View File

@@ -14,6 +14,9 @@ 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"
@@ -36,8 +39,9 @@ export default function LandingPage() {
];
const handleProductClick = (productId: string) => {
if (typeof window !== 'undefined') {
window.location.href = `/product/${productId}`;
const product = products.find(p => p.id === productId);
if (product) {
window.open(`/product/${productId}`, '_blank');
}
};
@@ -173,7 +177,7 @@ export default function LandingPage() {
<FaqBase
faqs={[
{
id: "faq-1", title: "What does the interactive product animation show?", content: "When you click on any fragrance, our signature animation begins: the product rotates smoothly leftward into view, followed by an immersive spray particle effect that dances across the screen. Product information—including notes, price, and description—gradually reveals behind the particles, creating a multisensory digital experience that mirrors the luxury of opening a premium fragrance bottle."
id: "faq-1", title: "What does the interactive product animation show?", content: "When you click on any fragrance, you're taken to a dedicated product page where our signature animation begins: the product rotates smoothly leftward into view, followed by an immersive spray particle effect that dances across the screen. Product information—including notes, price, and description—gradually reveals behind the particles, creating a multisensory digital experience that mirrors the luxury of opening a premium fragrance bottle."
},
{
id: "faq-2", title: "How do I know which fragrance is right for me?", content: "Each product includes detailed scent notes, concentration levels, and comprehensive descriptions. Our testimonial section features reviews from beauty professionals and fragrance enthusiasts. We also recommend exploring fragrances in the same family (floral, oriental, fresh, woody) to discover your signature scent. Contact our team for personalized recommendations."
@@ -265,4 +269,4 @@ export default function LandingPage() {
</div>
</ThemeProvider>
);
}
}

View File

@@ -1,30 +1,35 @@
"use client";
import { useParams } from "next/navigation";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
import FooterSimple from '@/components/sections/footer/FooterSimple';
import { useState, useMemo, useEffect } from 'react';
import Link from 'next/link';
import { useParams } from 'next/navigation';
import { useEffect, useState, useMemo } from 'react';
const products = [
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-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 delicate blend of jasmine, rose, and violet that captures the essence of an evening garden in full bloom. Perfect for those who appreciate floral elegance.", notes: ["Top: Bergamot, Lemon", "Heart: Jasmine, Rose, Violet", "Base: Sandalwood, Musk"],
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
},
{
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-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: "An intoxicating oriental fragrance featuring rich amber, exotic spices, and precious woods. A bold statement for those who dare to be different.", notes: ["Top: Black Pepper, Saffron", "Heart: Amber, Oud, Cinnamon", "Base: Cedarwood, Patchouli, Vanilla"],
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
},
{
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-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: "Warm and enveloping, this woody fragrance celebrates the depth of amber and exotic woods. A timeless signature for the sophisticated.", notes: ["Top: Ginger, Apple", "Heart: Amber, Cedarwood", "Base: Sandalwood, Vetiver, Tonka Bean"],
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
},
{
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-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 romantic fruity-floral composition centered around Damascus rose, complemented by juicy fruits. Celebrates the beauty of a perfect garden.", notes: ["Top: Peach, Blackcurrant", "Heart: Damascus Rose, Peonies", "Base: Musk, Amber"],
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
},
{
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-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 that evokes the freshness of sea spray and sun-kissed shores. Perfect for summer and everyday wear.", notes: ["Top: Lemon, Orange, Yuzu", "Heart: Sea Salt, Aquatic Accord", "Base: Driftwood, White Cedar"],
concentration: "Eau de Toilette (EDT) - 5-15% fragrance concentration"
},
{
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."
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 indulgent gourmand fragrance with creamy vanilla, caramel, and exotic spices. A sensual and comforting second skin.", notes: ["Top: Cardamom, Cinnamon", "Heart: Madagascar Vanilla, Caramel", "Base: Sandalwood, Amber, Tonka Bean"],
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
}
];
@@ -32,16 +37,11 @@ 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);
const [animationPhase, setAnimationPhase] = useState<'rotate' | 'spray' | 'reveal'>('rotate');
useEffect(() => {
const foundProduct = products.find(p => p.id === productId);
if (foundProduct) {
setProduct(foundProduct);
}
}, [productId]);
const product = PRODUCTS.find(p => p.id === productId);
// Generate particle animations with stable values
const particleAnimations = useMemo(() => {
return Array.from({ length: 12 }).map((_, i) => ({
id: i,
@@ -53,23 +53,26 @@ export default function ProductDetailPage() {
}, []);
useEffect(() => {
const rotationDuration = 2000;
const revealDelay = 1200;
const sprayDuration = 2000;
if (!showAnimation) return;
const rotateTimer = setTimeout(() => {
setAnimationPhase('spray');
}, 1000);
const animationTimer = setTimeout(() => {
const sprayTimer = setTimeout(() => {
setAnimationPhase('reveal');
}, 2000);
const finishTimer = setTimeout(() => {
setShowAnimation(false);
}, sprayDuration + rotationDuration);
const infoTimer = setTimeout(() => {
setInfoRevealed(true);
}, revealDelay + rotationDuration);
}, 3500);
return () => {
clearTimeout(animationTimer);
clearTimeout(infoTimer);
clearTimeout(rotateTimer);
clearTimeout(sprayTimer);
clearTimeout(finishTimer);
};
}, []);
}, [showAnimation]);
if (!product) {
return (
@@ -99,22 +102,14 @@ export default function ProductDetailPage() {
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 className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">Product Not Found</h1>
<p className="text-lg mb-8">Sorry, we couldn't find the product you're looking for.</p>
<Link href="/" className="text-primary-cta underline">
Return to Home
</Link>
</div>
</div>
</ThemeProvider>
);
@@ -148,204 +143,168 @@ export default function ProductDetailPage() {
/>
</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 className="min-h-screen pt-32 pb-20 px-4">
<div className="max-w-6xl mx-auto">
<Link href="/" className="text-primary-cta underline mb-8 inline-block">
Back to Shop
</Link>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-start">
{/* Product Image Section with Animation */}
<div className="relative h-96 lg:h-auto lg:aspect-square">
{showAnimation && (
<div className="absolute inset-0 pointer-events-none flex items-center justify-center z-50">
<div className="relative w-80 h-80">
{/* Product rotates leftward */}
<div
className="absolute inset-0"
style={{
animation: animationPhase === 'rotate' ? 'rotateLeftAnimation 1s ease-in-out forwards' : 'none',
transformOrigin: 'center',
}}
>
<img
src={product.imageSrc}
alt={product.imageAlt}
className="w-full h-full object-cover rounded-lg"
/>
</div>
{/* Spray particles animation */}
{animationPhase !== 'rotate' && (
<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: animationPhase === 'spray' ? 0.7 : 0,
transition: 'opacity 0.3s ease-out',
}}
/>
))}
</div>
)}
{/* Product information reveal overlay */}
{animationPhase === 'reveal' && (
<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 0.6s ease-in forwards',
}}
>
<div className="animate-fadeInUp">
<h3 className="text-3xl font-bold mb-2">{product.name}</h3>
<p className="text-sm mb-2 opacity-90">{product.variant}</p>
<p className="text-2xl font-semibold">{product.price}</p>
</div>
</div>
)}
</div>
<style>{`
@keyframes rotateLeftAnimation {
from {
transform: perspective(1000px) rotateY(0deg);
}
to {
transform: perspective(1000px) rotateY(-30deg);
}
}
@keyframes fall {
to {
transform: translateY(120px) translateX(var(--xOffset, 0px));
opacity: 0;
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fadeInUp {
animation: fadeInUp 0.8s ease-out forwards;
}
`}</style>
</div>
)}
{!showAnimation && (
<div className="w-full h-full rounded-lg overflow-hidden shadow-lg">
<img
src={product.imageSrc}
alt={product.imageAlt}
className="w-full h-full object-cover"
/>
</div>
)}
</div>
{/* Product Information Section */}
<div className={`transition-opacity duration-500 ${showAnimation && animationPhase !== 'reveal' ? 'opacity-0' : 'opacity-100'}`}>
<h1 className="text-5xl font-bold mb-2">{product.name}</h1>
<p className="text-lg text-foreground/70 mb-6">{product.variant}</p>
<p className="text-4xl font-bold text-primary-cta mb-8">{product.price}</p>
<div className="mb-8">
<p className="text-lg leading-relaxed mb-6">{product.description}</p>
<p className="text-sm text-foreground/60 italic">{product.concentration}</p>
</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 className="mb-8">
<h3 className="text-2xl font-bold mb-4">Fragrance Notes</h3>
<div className="space-y-3">
{product.notes.map((note, idx) => (
<div key={idx} className="flex items-start gap-3">
<div className="w-2 h-2 rounded-full bg-primary-cta mt-2 flex-shrink-0" />
<p className="text-foreground/80">{note}</p>
</div>
))}
</div>
</div>
<button
onClick={() => setShowAnimation(true)}
className="w-full bg-primary-cta text-primary-cta-text font-semibold py-3 px-6 rounded-lg hover:opacity-90 transition-opacity mb-4"
>
Add to Cart
</button>
<button
onClick={() => window.open('/', '_self')}
className="w-full bg-secondary-cta text-secondary-cta-text font-semibold py-3 px-6 rounded-lg hover:opacity-90 transition-opacity border border-foreground/20"
>
Continue Shopping
</button>
<div className="mt-8 pt-8 border-t border-foreground/10">
<h3 className="text-sm font-semibold mb-4">Why Choose This Fragrance?</h3>
<ul className="space-y-2 text-sm text-foreground/70">
<li> Sourced from master perfumers worldwide</li>
<li> 100% authentic luxury fragrance</li>
<li> Premium quality guaranteed</li>
<li> 30-day satisfaction guarantee</li>
<li> Complimentary gift wrapping available</li>
</ul>
</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>
);
}
}