feat(engagement): add Interactive Custom Studio Mood Board, 5-Star Client Reviews showcase, and smart booking prefill
This commit is contained in:
+5
-1
@@ -3,9 +3,11 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import Header from '@/components/Header';
|
||||
import Hero from '@/components/Hero';
|
||||
import PillarsSection from '@/components/PillarsSection';
|
||||
import PortfolioGallery from '@/components/PortfolioGallery';
|
||||
import MoodBoardEstimator from '@/components/MoodBoardEstimator';
|
||||
import PillarsSection from '@/components/PillarsSection';
|
||||
import ServicesSection from '@/components/ServicesSection';
|
||||
import TestimonialsSection from '@/components/TestimonialsSection';
|
||||
import AboutSection from '@/components/AboutSection';
|
||||
import BookingForm from '@/components/BookingForm';
|
||||
import Footer from '@/components/Footer';
|
||||
@@ -30,8 +32,10 @@ export default function Home() {
|
||||
<Header />
|
||||
<Hero />
|
||||
<PortfolioGallery />
|
||||
<MoodBoardEstimator />
|
||||
<PillarsSection />
|
||||
<ServicesSection />
|
||||
<TestimonialsSection />
|
||||
<AboutSection />
|
||||
<BookingForm />
|
||||
<Footer />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
export default function BookingForm() {
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
@@ -16,6 +16,21 @@ export default function BookingForm() {
|
||||
vision: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handlePrefill = (e: any) => {
|
||||
if (e.detail) {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
eventType: e.detail.eventType || prev.eventType,
|
||||
vision: e.detail.vision ? (prev.vision ? `${e.detail.vision}\n\nAdditional Notes:\n${prev.vision}` : e.detail.vision) : prev.vision,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('prefillWiseHeartedBooking', handlePrefill);
|
||||
return () => window.removeEventListener('prefillWiseHeartedBooking', handlePrefill);
|
||||
}, []);
|
||||
|
||||
const handleCheckbox = (service: string) => {
|
||||
setFormData(prev => {
|
||||
const exists = prev.services.includes(service);
|
||||
@@ -42,7 +57,7 @@ export default function BookingForm() {
|
||||
<div className="container" style={{ maxWidth: '920px' }}>
|
||||
|
||||
{/* Header */}
|
||||
<div style={{ textAlign: 'center', marginBottom: '36px', padding: '0 8px' }}>
|
||||
<div style={{ textAlign: 'center', marginBottom: '28px', padding: '0 8px' }}>
|
||||
<span style={{ fontSize: '0.85rem', fontWeight: 800, color: 'var(--color-pink-light)', letterSpacing: '0.15em', textTransform: 'uppercase', display: 'block', marginBottom: '10px' }}>
|
||||
Book Your Date
|
||||
</span>
|
||||
@@ -54,6 +69,26 @@ export default function BookingForm() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Live Availability Badge */}
|
||||
<div style={{
|
||||
background: 'rgba(212, 175, 55, 0.1)',
|
||||
border: '1px solid rgba(212, 175, 55, 0.4)',
|
||||
borderRadius: '50px',
|
||||
padding: '10px 20px',
|
||||
textAlign: 'center',
|
||||
maxWidth: '680px',
|
||||
margin: '0 auto 30px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '8px',
|
||||
fontSize: '0.85rem',
|
||||
color: '#F8FAF6',
|
||||
}}>
|
||||
<span style={{ color: '#10B981', fontSize: '0.9rem' }}>●</span>
|
||||
<span><strong>2026/2027 Calendar Open:</strong> Weekend dates book 4–8 weeks in advance. Reserve early to lock in your date!</span>
|
||||
</div>
|
||||
|
||||
{/* Form Box */}
|
||||
<div className="glass-panel" style={{
|
||||
padding: 'clamp(20px, 4vw, 36px)',
|
||||
|
||||
+50
-18
@@ -53,21 +53,24 @@ export default function Header() {
|
||||
</Link>
|
||||
|
||||
{/* Desktop Nav */}
|
||||
<nav style={{ display: 'flex', alignItems: 'center', gap: '28px' }} className="desktop-nav">
|
||||
<Link href="#about" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
About
|
||||
</Link>
|
||||
<Link href="#pillars" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
Brand Pillars
|
||||
</Link>
|
||||
<nav style={{ display: 'flex', alignItems: 'center', gap: '24px' }} className="desktop-nav">
|
||||
<Link href="#portfolio" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
Portfolio
|
||||
</Link>
|
||||
<Link href="#custom-studio" style={{ color: 'var(--color-pink-light)', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 700, transition: 'color 0.2s' }}>
|
||||
🎨 Design Studio
|
||||
</Link>
|
||||
<Link href="#pillars" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
Why Us
|
||||
</Link>
|
||||
<Link href="#services" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
Services
|
||||
Packages
|
||||
</Link>
|
||||
<Link href="#reviews" style={{ color: '#E2E8F0', textDecoration: 'none', fontSize: '0.92rem', fontWeight: 600, transition: 'color 0.2s' }}>
|
||||
Reviews
|
||||
</Link>
|
||||
<Link href="#contact" className="btn-gold" style={{ padding: '10px 24px', fontSize: '0.88rem' }}>
|
||||
Book Your Event ✨
|
||||
Book Event ✨
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
@@ -100,20 +103,49 @@ export default function Header() {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '18px',
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
<Link href="#about" onClick={() => setMobileMenuOpen(false)} style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.05rem', fontWeight: 600 }}>
|
||||
About
|
||||
<Link
|
||||
href="#portfolio"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.1rem', fontWeight: 600 }}
|
||||
>
|
||||
📸 Event Portfolio
|
||||
</Link>
|
||||
<Link href="#pillars" onClick={() => setMobileMenuOpen(false)} style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.05rem', fontWeight: 600 }}>
|
||||
Brand Pillars
|
||||
<Link
|
||||
href="#custom-studio"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
style={{ color: 'var(--color-pink-light)', textDecoration: 'none', fontSize: '1.1rem', fontWeight: 700 }}
|
||||
>
|
||||
🎨 Custom Design Studio
|
||||
</Link>
|
||||
<Link href="#portfolio" onClick={() => setMobileMenuOpen(false)} style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.05rem', fontWeight: 600 }}>
|
||||
Portfolio
|
||||
<Link
|
||||
href="#pillars"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.1rem', fontWeight: 600 }}
|
||||
>
|
||||
👑 Why Wise Hearted
|
||||
</Link>
|
||||
<Link href="#services" onClick={() => setMobileMenuOpen(false)} style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.05rem', fontWeight: 600 }}>
|
||||
Services
|
||||
<Link
|
||||
href="#services"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.1rem', fontWeight: 600 }}
|
||||
>
|
||||
🎈 Packages & Pricing
|
||||
</Link>
|
||||
<Link href="#contact" onClick={() => setMobileMenuOpen(false)} className="btn-pink" style={{ textAlign: 'center', justifyContent: 'center' }}>
|
||||
<Link
|
||||
href="#reviews"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
style={{ color: '#FFFFFF', textDecoration: 'none', fontSize: '1.1rem', fontWeight: 600 }}
|
||||
>
|
||||
⭐️ Client Reviews
|
||||
</Link>
|
||||
<Link
|
||||
href="#contact"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="btn-gold"
|
||||
style={{ padding: '12px', textAlign: 'center', justifyContent: 'center' }}
|
||||
>
|
||||
Book Your Event ✨
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface PaletteOption {
|
||||
id: string;
|
||||
name: string;
|
||||
colors: string[];
|
||||
desc: string;
|
||||
}
|
||||
|
||||
interface EventTypeOption {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
interface ElementOption {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
const eventTypes: EventTypeOption[] = [
|
||||
{ id: 'wedding', label: 'Wedding & Engagement', icon: '💍' },
|
||||
{ id: 'milestone_birthday', label: 'Milestone Birthday (30th/50th)', icon: '🎂' },
|
||||
{ id: 'baby_shower', label: 'Baby Shower / Gender Reveal', icon: '👶' },
|
||||
{ id: 'themed_party', label: 'Themed / 1st Birthday', icon: '🍓' },
|
||||
{ id: 'corporate_gala', label: 'Corporate Gala & Brand Launch', icon: '🥂' },
|
||||
];
|
||||
|
||||
const palettes: PaletteOption[] = [
|
||||
{
|
||||
id: 'royal_noir',
|
||||
name: 'Royal Noir Gala',
|
||||
colors: ['#000000', '#D4AF37', '#990000'],
|
||||
desc: 'Onyx black marble, reflective chrome gold, and deep crimson.',
|
||||
},
|
||||
{
|
||||
id: 'sweet_berry',
|
||||
name: 'Berry Sweet Pastel',
|
||||
colors: ['#E0006F', '#FFB6C1', '#002244'],
|
||||
desc: 'Strawberry red, blush baby pink, and deep midnight navy.',
|
||||
},
|
||||
{
|
||||
id: 'tuscan_garden',
|
||||
name: 'Tuscan Sunshine & Flora',
|
||||
colors: ['#F5C518', '#FFFFFF', '#4A5D4E'],
|
||||
desc: 'Warm sun yellow, crisp bridal white, and silk eucalyptus greenery.',
|
||||
},
|
||||
{
|
||||
id: 'tropical_neon',
|
||||
name: 'Tropical Luxe Brights',
|
||||
colors: ['#FF007F', '#FF6600', '#00F0FF'],
|
||||
desc: 'Vibrant hot pink, electric orange, and bright turquoise.',
|
||||
},
|
||||
{
|
||||
id: 'celestial_moon',
|
||||
name: 'Midnight & Gold Moon',
|
||||
colors: ['#0B1B3D', '#C8A2C8', '#D4AF37'],
|
||||
desc: 'Royal navy, soft lavender drape, and gold starburst accents.',
|
||||
},
|
||||
];
|
||||
|
||||
const decorElements: ElementOption[] = [
|
||||
{ id: 'balloon_cascade', label: 'Organic Balloon Cloud Cascade', icon: '🎈', tag: 'Most Popular' },
|
||||
{ id: 'arch_panels', label: 'Custom Multi-Arch Wood Panels', icon: '🏛️', tag: 'Signature' },
|
||||
{ id: 'mosaic_letters', label: 'Giant 3D Balloon Mosaic Letters', icon: '🔤', tag: 'High Impact' },
|
||||
{ id: 'beverage_station', label: 'Arched Drink & Treat Station', icon: '🍸', tag: 'Interactive' },
|
||||
{ id: 'floral_accents', label: 'Silk Florals & Botanical Sprigs', icon: '🌹', tag: 'Luxury' },
|
||||
{ id: 'custom_lettering', label: '3D Gold Script Custom Name Sign', icon: '✨', tag: 'Personalized' },
|
||||
];
|
||||
|
||||
export default function MoodBoardEstimator() {
|
||||
const [selectedEventType, setSelectedEventType] = useState<string>('milestone_birthday');
|
||||
const [selectedPalette, setSelectedPalette] = useState<string>('royal_noir');
|
||||
const [selectedElements, setSelectedElements] = useState<string[]>([
|
||||
'balloon_cascade',
|
||||
'arch_panels',
|
||||
'custom_lettering',
|
||||
]);
|
||||
|
||||
const toggleElement = (id: string) => {
|
||||
setSelectedElements((prev) =>
|
||||
prev.includes(id) ? prev.filter((el) => el !== id) : [...prev, id]
|
||||
);
|
||||
};
|
||||
|
||||
const currentEventType = eventTypes.find((e) => e.id === selectedEventType)?.label || '';
|
||||
const currentPalette = palettes.find((p) => p.id === selectedPalette);
|
||||
const selectedElementLabels = decorElements
|
||||
.filter((e) => selectedElements.includes(e.id))
|
||||
.map((e) => e.label);
|
||||
|
||||
const handleApplyToBooking = () => {
|
||||
const visionString = `Custom Design Studio Selection:
|
||||
• Celebration: ${currentEventType}
|
||||
• Color Palette: ${currentPalette?.name} (${currentPalette?.desc})
|
||||
• Core Decor Elements: ${selectedElementLabels.join(', ')}`;
|
||||
|
||||
// Dispatch custom event to prefill booking form
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('prefillWiseHeartedBooking', {
|
||||
detail: {
|
||||
eventType: currentEventType,
|
||||
vision: visionString,
|
||||
services: selectedElementLabels,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Smoothly scroll to contact form
|
||||
const contactSection = document.getElementById('contact');
|
||||
if (contactSection) {
|
||||
contactSection.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section
|
||||
id="custom-studio"
|
||||
style={{
|
||||
padding: 'clamp(70px, 10vw, 110px) 0',
|
||||
backgroundColor: '#050505',
|
||||
position: 'relative',
|
||||
borderBottom: '1px solid var(--border-gold)',
|
||||
}}
|
||||
>
|
||||
<div className="container" style={{ maxWidth: '1120px' }}>
|
||||
{/* Section Header */}
|
||||
<div style={{ textAlign: 'center', marginBottom: '45px', padding: '0 8px' }}>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.85rem',
|
||||
fontWeight: 800,
|
||||
color: 'var(--color-pink-light)',
|
||||
letterSpacing: '0.15em',
|
||||
textTransform: 'uppercase',
|
||||
display: 'block',
|
||||
marginBottom: '10px',
|
||||
}}
|
||||
>
|
||||
🎨 Interactive Custom Studio
|
||||
</span>
|
||||
<h2
|
||||
style={{
|
||||
fontSize: 'clamp(2rem, 3.8vw, 2.8rem)',
|
||||
fontWeight: 800,
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
>
|
||||
Design Your <span className="gold-gradient-text">Dream Setup</span>
|
||||
</h2>
|
||||
<p
|
||||
style={{
|
||||
fontSize: '1.05rem',
|
||||
color: '#94A3B8',
|
||||
maxWidth: '700px',
|
||||
margin: '0 auto',
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
Select your celebration type, color palette, and preferred backdrop elements below to generate your personalized setup preview in real time!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 3-Step Interactive Grid */}
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
|
||||
gap: '24px',
|
||||
marginBottom: '40px',
|
||||
}}
|
||||
>
|
||||
{/* STEP 1: Celebration Type */}
|
||||
<div
|
||||
className="glass-panel"
|
||||
style={{
|
||||
padding: '24px 20px',
|
||||
border: '1px solid rgba(212, 175, 55, 0.3)',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '16px' }}>
|
||||
<span
|
||||
style={{
|
||||
background: 'var(--color-gold-gradient)',
|
||||
color: '#000',
|
||||
width: '26px',
|
||||
height: '26px',
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontWeight: 800,
|
||||
fontSize: '0.85rem',
|
||||
}}
|
||||
>
|
||||
1
|
||||
</span>
|
||||
<h3 style={{ fontSize: '1.15rem', fontWeight: 800, color: '#FFFFFF', margin: 0 }}>
|
||||
Celebration Type
|
||||
</h3>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
{eventTypes.map((et) => {
|
||||
const isSelected = selectedEventType === et.id;
|
||||
return (
|
||||
<button
|
||||
key={et.id}
|
||||
type="button"
|
||||
onClick={() => setSelectedEventType(et.id)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
padding: '12px 14px',
|
||||
borderRadius: '12px',
|
||||
background: isSelected ? 'rgba(212, 175, 55, 0.15)' : 'rgba(255, 255, 255, 0.03)',
|
||||
border: isSelected ? '1.5px solid var(--color-gold)' : '1px solid rgba(255, 255, 255, 0.08)',
|
||||
color: isSelected ? '#FFFFFF' : '#CBD5E1',
|
||||
fontSize: '0.92rem',
|
||||
fontWeight: isSelected ? 700 : 500,
|
||||
cursor: 'pointer',
|
||||
textAlign: 'left',
|
||||
transition: 'all 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: '1.25rem' }}>{et.icon}</span>
|
||||
<span>{et.label}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* STEP 2: Color Palette */}
|
||||
<div
|
||||
className="glass-panel"
|
||||
style={{
|
||||
padding: '24px 20px',
|
||||
border: '1px solid rgba(224, 0, 111, 0.3)',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '16px' }}>
|
||||
<span
|
||||
style={{
|
||||
background: 'var(--color-pink-gradient)',
|
||||
color: '#FFF',
|
||||
width: '26px',
|
||||
height: '26px',
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontWeight: 800,
|
||||
fontSize: '0.85rem',
|
||||
}}
|
||||
>
|
||||
2
|
||||
</span>
|
||||
<h3 style={{ fontSize: '1.15rem', fontWeight: 800, color: '#FFFFFF', margin: 0 }}>
|
||||
Signature Palette
|
||||
</h3>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
{palettes.map((p) => {
|
||||
const isSelected = selectedPalette === p.id;
|
||||
return (
|
||||
<button
|
||||
key={p.id}
|
||||
type="button"
|
||||
onClick={() => setSelectedPalette(p.id)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '4px',
|
||||
padding: '12px 14px',
|
||||
borderRadius: '12px',
|
||||
background: isSelected ? 'rgba(224, 0, 111, 0.15)' : 'rgba(255, 255, 255, 0.03)',
|
||||
border: isSelected ? '1.5px solid var(--color-pink-light)' : '1px solid rgba(255, 255, 255, 0.08)',
|
||||
cursor: 'pointer',
|
||||
textAlign: 'left',
|
||||
transition: 'all 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
||||
<span style={{ fontSize: '0.92rem', fontWeight: isSelected ? 700 : 600, color: isSelected ? '#FFFFFF' : '#CBD5E1' }}>
|
||||
{p.name}
|
||||
</span>
|
||||
<div style={{ display: 'flex', gap: '4px' }}>
|
||||
{p.colors.map((c, i) => (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
width: '14px',
|
||||
height: '14px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: c,
|
||||
border: '1px solid rgba(255,255,255,0.4)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<span style={{ fontSize: '0.78rem', color: '#94A3B8' }}>{p.desc}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* STEP 3: Decor Elements */}
|
||||
<div
|
||||
className="glass-panel"
|
||||
style={{
|
||||
padding: '24px 20px',
|
||||
border: '1px solid rgba(212, 175, 55, 0.3)',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '16px' }}>
|
||||
<span
|
||||
style={{
|
||||
background: 'var(--color-gold-gradient)',
|
||||
color: '#000',
|
||||
width: '26px',
|
||||
height: '26px',
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontWeight: 800,
|
||||
fontSize: '0.85rem',
|
||||
}}
|
||||
>
|
||||
3
|
||||
</span>
|
||||
<h3 style={{ fontSize: '1.15rem', fontWeight: 800, color: '#FFFFFF', margin: 0 }}>
|
||||
Backdrop & Elements
|
||||
</h3>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
{decorElements.map((el) => {
|
||||
const isSelected = selectedElements.includes(el.id);
|
||||
return (
|
||||
<button
|
||||
key={el.id}
|
||||
type="button"
|
||||
onClick={() => toggleElement(el.id)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '10px 12px',
|
||||
borderRadius: '12px',
|
||||
background: isSelected ? 'rgba(212, 175, 55, 0.15)' : 'rgba(255, 255, 255, 0.03)',
|
||||
border: isSelected ? '1.5px solid var(--color-gold)' : '1px solid rgba(255, 255, 255, 0.08)',
|
||||
color: isSelected ? '#FFFFFF' : '#CBD5E1',
|
||||
fontSize: '0.88rem',
|
||||
fontWeight: isSelected ? 700 : 500,
|
||||
cursor: 'pointer',
|
||||
textAlign: 'left',
|
||||
transition: 'all 0.2s ease',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span>{el.icon}</span>
|
||||
<span>{el.label}</span>
|
||||
</div>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.72rem',
|
||||
fontWeight: 700,
|
||||
color: isSelected ? 'var(--color-gold-light)' : '#64748B',
|
||||
background: isSelected ? 'rgba(212, 175, 55, 0.2)' : 'transparent',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '6px',
|
||||
}}
|
||||
>
|
||||
{isSelected ? '✓ Added' : '+ Add'}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Live Customized Preview Banner & CTA */}
|
||||
<div
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(10, 10, 10, 0.98) 100%)',
|
||||
border: '2px solid var(--color-gold)',
|
||||
borderRadius: '24px',
|
||||
padding: '24px 28px',
|
||||
boxShadow: '0 20px 50px rgba(0,0,0,0.8), 0 0 30px rgba(212, 175, 55, 0.2)',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: '20px',
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: '1 1 400px' }}>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.8rem',
|
||||
fontWeight: 800,
|
||||
color: 'var(--color-pink-light)',
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
display: 'block',
|
||||
marginBottom: '6px',
|
||||
}}
|
||||
>
|
||||
✦ YOUR CUSTOM EVENT SPECIFICATION ✦
|
||||
</span>
|
||||
<div style={{ fontSize: '1.25rem', fontWeight: 800, color: '#FFFFFF', marginBottom: '8px' }}>
|
||||
{currentEventType} <span style={{ color: 'var(--color-gold)' }}>•</span> {currentPalette?.name}
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', marginTop: '4px' }}>
|
||||
{selectedElementLabels.map((lbl, idx) => (
|
||||
<span
|
||||
key={idx}
|
||||
style={{
|
||||
fontSize: '0.78rem',
|
||||
background: 'rgba(255, 255, 255, 0.08)',
|
||||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||||
padding: '3px 8px',
|
||||
borderRadius: '8px',
|
||||
color: '#E2E8F0',
|
||||
}}
|
||||
>
|
||||
{lbl}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleApplyToBooking}
|
||||
className="btn-gold"
|
||||
style={{
|
||||
padding: '16px 32px',
|
||||
fontSize: '1rem',
|
||||
fontWeight: 800,
|
||||
cursor: 'pointer',
|
||||
boxShadow: '0 6px 25px rgba(212, 175, 55, 0.5)',
|
||||
}}
|
||||
>
|
||||
<span>✨</span> Lock In Design & Get Quote →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface Testimonial {
|
||||
name: string;
|
||||
role: string;
|
||||
celebration: string;
|
||||
quote: string;
|
||||
rating: number;
|
||||
highlight: string;
|
||||
}
|
||||
|
||||
const testimonials: Testimonial[] = [
|
||||
{
|
||||
name: 'Titus & Alayna M.',
|
||||
role: 'Bride & Groom',
|
||||
celebration: 'Tuscan Wedding Arch',
|
||||
quote: 'Jackie brought our dream wedding to life. The Tuscan yellow arch paired with the white floral balloon clouds took everyone’s breath away. Her faith, care, and attention to every balloon placement was extraordinary!',
|
||||
rating: 5,
|
||||
highlight: 'Pure perfection & photo-ready',
|
||||
},
|
||||
{
|
||||
name: 'Emelda G.',
|
||||
role: 'Birthday Celebrant',
|
||||
celebration: '50th Milestone Gala',
|
||||
quote: 'The black marble backdrop with the gold chrome and crimson organic garland was the centerpiece of the entire night. My guests could not stop taking photos! Jackie handled setup and teardown flawlessly.',
|
||||
rating: 5,
|
||||
highlight: 'Show-stopping centerpiece',
|
||||
},
|
||||
{
|
||||
name: 'Jessica R.',
|
||||
role: 'Mom & Host',
|
||||
celebration: 'Berry Sweet Baby Shower',
|
||||
quote: 'From the moment I contacted Jackie, she understood the vision for my baby shower. The custom triple arch with strawberry and blueberry motifs was sweeter than anything on Pinterest!',
|
||||
rating: 5,
|
||||
highlight: 'Better than Pinterest',
|
||||
},
|
||||
{
|
||||
name: 'Marcus & Danielle S.',
|
||||
role: 'Parents',
|
||||
celebration: 'Class of 2026 Graduation Gala',
|
||||
quote: 'The tropical vibrant neon balloon arch and palm leaf styling gave our celebration so much life and energy. Jackie is professional, on time, and an absolute joy to work with.',
|
||||
rating: 5,
|
||||
highlight: 'Unmatched energy & joy',
|
||||
},
|
||||
];
|
||||
|
||||
export default function TestimonialsSection() {
|
||||
return (
|
||||
<section
|
||||
id="reviews"
|
||||
style={{
|
||||
padding: 'clamp(60px, 10vw, 100px) 0',
|
||||
backgroundColor: '#000000',
|
||||
position: 'relative',
|
||||
borderBottom: '1px solid var(--border-gold)',
|
||||
}}
|
||||
>
|
||||
<div className="container" style={{ maxWidth: '1180px' }}>
|
||||
{/* Section Header */}
|
||||
<div style={{ textAlign: 'center', marginBottom: '45px', padding: '0 8px' }}>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.85rem',
|
||||
fontWeight: 800,
|
||||
color: 'var(--color-pink-light)',
|
||||
letterSpacing: '0.15em',
|
||||
textTransform: 'uppercase',
|
||||
display: 'block',
|
||||
marginBottom: '10px',
|
||||
}}
|
||||
>
|
||||
⭐️ Client Love & Trust
|
||||
</span>
|
||||
<h2
|
||||
style={{
|
||||
fontSize: 'clamp(2rem, 3.8vw, 2.8rem)',
|
||||
fontWeight: 800,
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
>
|
||||
Memories Crafted with <span className="gold-gradient-text">Heart & Faith</span>
|
||||
</h2>
|
||||
<p
|
||||
style={{
|
||||
fontSize: '1.05rem',
|
||||
color: '#94A3B8',
|
||||
maxWidth: '680px',
|
||||
margin: '0 auto',
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
See how Wise Hearted Event Decor transforms milestone birthdays, weddings, baby showers, and celebrations into unforgettable photo moments.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 4 Testimonials Grid */}
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))',
|
||||
gap: '20px',
|
||||
}}
|
||||
>
|
||||
{testimonials.map((t, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="glass-panel"
|
||||
style={{
|
||||
padding: '28px 22px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
border: '1px solid rgba(212, 175, 55, 0.25)',
|
||||
borderRadius: '18px',
|
||||
transition: 'transform 0.3s ease, border-color 0.3s ease',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{/* Rating Stars */}
|
||||
<div style={{ display: 'flex', gap: '3px', marginBottom: '14px', color: '#D4AF37', fontSize: '1rem' }}>
|
||||
{'★'.repeat(t.rating)}
|
||||
</div>
|
||||
|
||||
{/* Highlight Tag */}
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
fontSize: '0.75rem',
|
||||
fontWeight: 700,
|
||||
color: 'var(--color-pink-light)',
|
||||
background: 'rgba(224, 0, 111, 0.15)',
|
||||
padding: '3px 8px',
|
||||
borderRadius: '6px',
|
||||
marginBottom: '12px',
|
||||
}}
|
||||
>
|
||||
{t.highlight}
|
||||
</span>
|
||||
|
||||
{/* Quote */}
|
||||
<p style={{ fontSize: '0.92rem', color: '#E2E8F0', lineHeight: 1.65, fontStyle: 'italic', marginBottom: '20px' }}>
|
||||
“{t.quote}”
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Author Footer */}
|
||||
<div style={{ borderTop: '1px solid rgba(255,255,255,0.08)', paddingTop: '14px' }}>
|
||||
<div style={{ fontSize: '0.96rem', fontWeight: 800, color: 'var(--color-gold-light)' }}>
|
||||
{t.name}
|
||||
</div>
|
||||
<div style={{ fontSize: '0.8rem', color: '#94A3B8' }}>
|
||||
{t.role} • <span style={{ color: '#CBD5E1' }}>{t.celebration}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user