Files
wise-hearted-decor/src/components/PortfolioGallery.tsx
T

410 lines
15 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import Image from 'next/image';
import { Camera, Sparkles, X, ChevronRight } from 'lucide-react';
interface GalleryItem {
id: number;
title: string;
category: string;
desc: string;
image: string;
tag: string;
}
const portfolioItems: GalleryItem[] = [
{
id: 1,
title: 'Outdoor Ceremony Arch with Sage Drapery',
category: 'Weddings',
desc: 'Wooden ceremony arch accented with soft sage and ivory drapery, fresh white roses, and matching floral arrangements on gold stands.',
image: '/images/portfolio_outdoor_ceremony_arch_sage_roses.jpg',
tag: 'Ceremony Arches',
},
{
id: 2,
title: 'Indoor Wedding Arch with Cascading Drapery',
category: 'Weddings',
desc: 'Romantic sheer white backdrop with cascading fabric, lush burgundy roses, blush florals, and natural botanical greenery.',
image: '/images/portfolio_indoor_wedding_arch_burgundy_roses.jpg',
tag: 'Wedding Backdrops',
},
{
id: 3,
title: 'Tuscan Multi-Arch Ceremony Backdrop',
category: 'Weddings',
desc: 'Tuscan yellow centerpiece arch flanked by crisp white panels, organic lemon-white balloon clouds, and white floral arrangements.',
image: '/images/portfolio_titus_alayna_wedding.webp',
tag: 'Multi-Arch Staging',
},
{
id: 4,
title: 'Black, Gold & Crimson Milestone Backdrop',
category: 'Birthdays',
desc: 'Black marble backdrop with gold script lettering, surrounded by a dramatic organic garland of chrome gold, crimson red, and onyx black balloons.',
image: '/images/portfolio_emelda_luxury_black_gold.webp',
tag: 'Milestone Celebrations',
},
{
id: 5,
title: '70th Milestone Birthday Balloon Arch',
category: 'Birthdays',
desc: 'Arched black backdrop with custom gold script lettering, framed in a luxury cascading organic garland of chrome gold and onyx balloons.',
image: '/images/portfolio_70th_birthday_black_gold_balloon_arch.jpg',
tag: 'Milestone Birthdays',
},
{
id: 6,
title: 'Berry Sweet Triple Arch Backdrop',
category: 'Baby Showers',
desc: 'Triple custom arched panels with hand-illustrated berry motifs, framed in organic strawberry red, navy blue, and pastel pink balloons.',
image: '/images/portfolio_berry_sweet_baby.webp',
tag: 'Baby Showers',
},
{
id: 7,
title: 'Berry First Birthday Theme Arch',
category: 'Birthdays',
desc: 'Custom arched backdrop with 3D strawberry foil balloons and an organic balloon cascade in cherry red, blush pink, and white.',
image: '/images/portfolio_amina_berry_first_birthday.webp',
tag: '1st Birthdays',
},
{
id: 8,
title: 'Sage Green & Gold Chiara Arch Backdrop',
category: 'Birthdays',
desc: 'Elegant white arch with 3D gold lettering, accented with faux eucalyptus greenery, silk roses, and chrome gold balloon spheres.',
image: '/images/portfolio_sage_gold_birthday.webp',
tag: 'Chiara Arches',
},
{
id: 9,
title: 'Sports & Soccer Column Installation',
category: 'Themed',
desc: 'Dynamic balloon column installation with royal blue, vibrant orange, white accents, and foil soccer balls for athletic banquets and parties.',
image: '/images/portfolio_soccer_sports_balloon_column.jpg',
tag: 'Sports Celebrations',
},
{
id: 10,
title: 'Gold Sequin & Velvet Drape Backdrop',
category: 'Specialty',
desc: 'Opulent indoor staging featuring sheer white center drapes, gold sequin panels, and deep crimson velvet curtains with gold tiebacks.',
image: '/images/portfolio_gold_sequin_crimson_drapery_backdrop.jpg',
tag: 'Drape Backdrops',
},
{
id: 11,
title: 'Custom Anniversary Theme & Balloon Sculpture',
category: 'Themed',
desc: 'Custom arched stage backdrop with personalized anniversary signage and a high-impact themed balloon bottle art installation.',
image: '/images/portfolio_chappell_anniversary_diet_coke_balloons.jpg',
tag: 'Custom Installations',
},
{
id: 12,
title: 'Tropical Brights Graduation Backdrop',
category: 'Themed',
desc: 'Vibrant tropical color palette of hot pink, neon orange, bright turquoise, and lime green with monstera palm leaves on a lavender backdrop.',
image: '/images/portfolio_tropical_class_2026.webp',
tag: 'Graduations',
},
{
id: 13,
title: 'Lavender Moon Arch & Mosaic Lettering',
category: 'Specialty',
desc: 'Gold crescent moon hoop with deep navy and lilac balloons, paired with sheer lilac drape backdrops and custom balloon mosaic lettering.',
image: '/images/portfolio_lavender_moon_arch.webp',
tag: 'Mosaic Lettering',
},
{
id: 14,
title: 'Holiday Patriotic Celebration Arch',
category: 'Themed',
desc: 'Grand red, white, royal blue, and chrome gold balloon arch featuring metallic 3D starburst foils for a high-impact holiday installation.',
image: '/images/portfolio_memorial_day_arch.webp',
tag: 'Holiday Events',
},
{
id: 15,
title: 'Citrus Themed Organic Balloon Wave',
category: 'Specialty',
desc: 'Vibrant orange and pearl white organic balloon wave framing a custom refreshment display with rustic wooden beverage crates.',
image: '/images/portfolio_pop_fizz_orange.webp',
tag: 'Organic Styling',
},
];
export default function PortfolioGallery() {
const [selectedCategory, setSelectedCategory] = useState('All');
const [activeModalImage, setActiveModalImage] = useState<GalleryItem | null>(null);
const categories = ['All', 'Weddings', 'Birthdays', 'Baby Showers', 'Themed', 'Specialty'];
const filteredItems = selectedCategory === 'All'
? portfolioItems
: portfolioItems.filter(item => item.category === selectedCategory);
return (
<section id="portfolio" style={{
padding: '90px 24px',
backgroundColor: '#FAF8F5',
position: 'relative',
borderBottom: '1px solid #E5E7EB',
}}>
<div className="container">
{/* Section Header */}
<div style={{ textAlign: 'center', marginBottom: '40px' }}>
<span style={{ fontSize: '0.85rem', fontWeight: 800, color: 'var(--color-gold-dark)', letterSpacing: '0.15em', textTransform: 'uppercase', display: 'block', marginBottom: '10px' }}>
Real Client Installations
</span>
<h2 style={{ fontSize: 'clamp(2rem, 3.8vw, 2.8rem)', fontWeight: 800, color: 'var(--text-dark)', marginBottom: '16px', lineHeight: 1.25 }}>
Our Event <span className="gold-gradient-text">Portfolio</span>
</h2>
<p style={{ fontSize: '1.08rem', color: '#4B5563', maxWidth: '650px', margin: '0 auto', lineHeight: 1.7 }}>
Explore our custom Chiara arches, elegant drape backdrops, organic balloon garlands, and bespoke event styling created for celebrations across Southern California.
</p>
</div>
{/* Category Filter Pills */}
<div style={{
display: 'flex',
justifyContent: 'center',
gap: '10px',
flexWrap: 'wrap',
marginBottom: '44px',
}}>
{categories.map((cat) => (
<button
key={cat}
onClick={() => setSelectedCategory(cat)}
style={{
padding: '9px 20px',
borderRadius: '50px',
fontSize: '0.88rem',
fontWeight: 700,
border: selectedCategory === cat
? '1.5px solid var(--color-gold-dark)'
: '1px solid #E5E7EB',
backgroundColor: selectedCategory === cat
? 'var(--color-gold-dark)'
: '#FFFFFF',
color: selectedCategory === cat
? '#FFFFFF'
: '#4B5563',
cursor: 'pointer',
transition: 'all 0.2s ease',
boxShadow: selectedCategory === cat
? '0 4px 12px rgba(150, 113, 23, 0.25)'
: '0 1px 3px rgba(0, 0, 0, 0.05)',
}}
>
{cat}
</button>
))}
</div>
{/* Gallery Grid */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(310px, 1fr))',
gap: '26px',
}}>
{filteredItems.map((item) => (
<div
key={item.id}
onClick={() => setActiveModalImage(item)}
style={{
background: '#FFFFFF',
borderRadius: '18px',
overflow: 'hidden',
border: '1px solid #E5E7EB',
boxShadow: '0 4px 16px rgba(0, 0, 0, 0.04)',
cursor: 'pointer',
transition: 'all 0.3s ease',
display: 'flex',
flexDirection: 'column',
}}
className="gallery-card"
>
{/* Image Container */}
<div style={{
position: 'relative',
width: '100%',
height: '320px',
backgroundColor: '#F3F4F6',
}}>
<Image
src={item.image}
alt={item.title}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
style={{ objectFit: 'cover' }}
/>
{/* Floating Category Tag */}
<div style={{
position: 'absolute',
top: '12px',
left: '12px',
background: 'rgba(255, 255, 255, 0.94)',
backdropFilter: 'blur(8px)',
padding: '5px 12px',
borderRadius: '50px',
fontSize: '0.74rem',
fontWeight: 800,
color: 'var(--color-gold-dark)',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
border: '1px solid rgba(197, 160, 89, 0.3)',
}}>
{item.tag}
</div>
</div>
{/* Card Meta Content */}
<div style={{ padding: '20px 20px 22px', flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
<div>
<h3 style={{
fontSize: '1.12rem',
fontWeight: 800,
color: 'var(--text-dark)',
marginBottom: '8px',
lineHeight: 1.35,
}}>
{item.title}
</h3>
<p style={{
fontSize: '0.88rem',
color: '#6B7280',
lineHeight: 1.6,
margin: 0,
}}>
{item.desc}
</p>
</div>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '6px',
color: 'var(--color-gold-dark)',
fontSize: '0.84rem',
fontWeight: 700,
marginTop: '16px',
paddingTop: '12px',
borderTop: '1px solid #F3F4F6',
}}>
<span>View Full Setup</span> <ChevronRight size={14} />
</div>
</div>
</div>
))}
</div>
{/* Modal Lightbox */}
{activeModalImage && (
<div
onClick={() => setActiveModalImage(null)}
style={{
position: 'fixed',
inset: 0,
zIndex: 99999,
backgroundColor: 'rgba(0, 0, 0, 0.88)',
backdropFilter: 'blur(12px)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '20px',
}}
>
<div
onClick={(e) => e.stopPropagation()}
style={{
position: 'relative',
maxWidth: '850px',
width: '100%',
maxHeight: '90vh',
backgroundColor: '#FFFFFF',
borderRadius: '20px',
overflow: 'hidden',
boxShadow: '0 25px 60px rgba(0, 0, 0, 0.5)',
display: 'flex',
flexDirection: 'column',
}}
>
<button
onClick={() => setActiveModalImage(null)}
style={{
position: 'absolute',
top: '16px',
right: '16px',
zIndex: 10,
width: '38px',
height: '38px',
borderRadius: '50%',
background: 'rgba(0, 0, 0, 0.65)',
border: 'none',
color: '#FFFFFF',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
}}
aria-label="Close Preview"
>
<X size={20} />
</button>
<div style={{
position: 'relative',
width: '100%',
height: 'clamp(320px, 55vh, 520px)',
backgroundColor: '#111',
}}>
<Image
src={activeModalImage.image}
alt={activeModalImage.title}
fill
style={{ objectFit: 'contain' }}
/>
</div>
<div style={{ padding: '24px' }}>
<div style={{
display: 'inline-block',
background: 'rgba(197, 160, 89, 0.15)',
color: 'var(--color-gold-dark)',
padding: '4px 12px',
borderRadius: '50px',
fontSize: '0.78rem',
fontWeight: 800,
marginBottom: '8px',
}}>
{activeModalImage.tag}
</div>
<h3 style={{ fontSize: '1.4rem', fontWeight: 800, color: 'var(--text-dark)', marginBottom: '8px' }}>
{activeModalImage.title}
</h3>
<p style={{ fontSize: '0.96rem', color: '#4B5563', lineHeight: 1.6, marginBottom: '20px' }}>
{activeModalImage.desc}
</p>
<a
href="#contact"
onClick={() => setActiveModalImage(null)}
className="btn-gold"
style={{ padding: '12px 28px', fontSize: '0.92rem' }}
>
<Sparkles size={16} /> Inquire About This Backdrop Design
</a>
</div>
</div>
</div>
)}
</div>
</section>
);
}