Commit 56d72d1d by PLN (Algolia)

wip

parent 133e522c
......@@ -25,22 +25,24 @@ export default function ParVaguesFooter() {
{/* About Column */}
<div>
<p className="text-gray-400 text-sm mb-4">
Livecoding de musique open-source avec TidalCycles et contrôleur MIDI.<br />
Performances algorithmiques et création sonore en direct.
Livecoding de musique libre<br />
Performances algorithmiques en direct.
</p>
</div>
{/* Social Column */}
<div className="flex flex-col items-center md:items-end">
<div className="flex justify-center mb-4 md:mb-0 md:absolute md:left-1/2 md:transform md:-translate-x-1/2">
<div className="flex justify-center w-full">
<div className="relative">
<Image
src="/images/parvagues/logo_text.png"
src="/images/parvagues/logo.png"
alt="ParVagues Logo"
width={96}
height={96}
className="md:mt-16"
width={240}
height={240}
className="mx-auto mb-4"
/>
</div>
</div>
<div className="flex flex-wrap gap-4 justify-center md:justify-end">
{socialLinks.map((link, index) => (
......@@ -60,30 +62,26 @@ export default function ParVaguesFooter() {
</div>
{/* Navigation Links - more compact */}
<div className="w-full bg-black py-4 my-4">
<div className="flex justify-center items-center space-x-4 text-xs tracking-widest uppercase flex-wrap">
<Link href="/parvagues#music" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<div className="w-full bg-black py-4">
<div className="flex justify-center items-center space-x-8 text-xs tracking-widest uppercase flex-wrap">
<Link href="/parvagues#music" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
MUSIQUE
</Link>
<Link href="/parvagues#performances" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#performances" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
PERFORMANCES
</Link>
<Link href="/parvagues#about" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#about" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
À PROPOS
</Link>
<a
href="mailto:parvagues@nech.pl?subject=Booking Request"
className="text-gray-300 hover:text-[#ff3d7b] transition-colors"
className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3"
>
RÉSERVER
</a>
</div>
</div>
{/* Bottom Bar */}
<div className="border-t border-gray-800 mt-4 pt-4 text-center text-gray-500 text-xs">
<p>© {year} ParVagues. All code is open-source.</p>
</div>
</div>
</footer>
);
......
......@@ -31,28 +31,30 @@ export default function ParVaguesHeader({ eventName = null, title = null }) {
const headerTitle = title || eventName || 'ParVagues';
return (
<header
className="sticky top-0 left-0 w-full z-50 bg-black/80 backdrop-blur-md border-b border-[#d900ff]/20 shadow-lg transition-all duration-300"
>
<div className="max-w-6xl mx-auto px-4 py-3 flex justify-between items-center">
<div className="flex items-center gap-2">
<Link href="/parvagues" className="flex items-center">
<header className="sticky top-0 left-0 w-full z-50 bg-black/80 backdrop-blur-md border-b border-[#d900ff]/20">
<div className={`${styles.neonGradient} opacity-5`}></div>
<div className="max-w-6xl mx-auto px-4 py-3 flex justify-between items-center relative">
<div className="flex items-center">
<Link href="/parvagues" className="flex items-center group">
<div className="h-10 w-auto relative">
<Image
src="/images/parvagues/logo_transparent.png"
alt="ParVagues Logo"
width={40}
height={40}
className="object-contain"
width={200}
height={200}
className="object-contain transition-all duration-300 group-hover:filter group-hover:drop-shadow-[0_0_8px_rgba(217,0,255,0.7)]"
/>
</div>
{/* Title animation based on scroll */}
<div className="overflow-hidden ml-2">
<span
className={`text-[#d900ff] text-xl font-bold transform transition-all duration-500 ${
className={`text-white font-bold transition-all duration-500 ${
showInHeader ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-8'
}`}
style={{
textShadow: '0 0 5px rgba(217, 0, 255, 0.7), 0 0 10px rgba(217, 0, 255, 0.5)',
color: 'var(--neon-high)'
}}
>
{headerTitle}
</span>
......@@ -61,25 +63,25 @@ export default function ParVaguesHeader({ eventName = null, title = null }) {
</div>
{/* Navigation Links */}
<div className="hidden md:flex items-center space-x-6 text-sm">
<Link href="/parvagues#music" className="text-white hover:text-[#ff3d7b] transition-colors">
<nav className="hidden md:flex items-center space-x-6 text-sm tracking-wider">
<Link href="/parvagues#music" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
Music
</Link>
<Link href="/parvagues#performances" className="text-white hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#performances" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
Performances
</Link>
<Link href="/parvagues#about" className="text-white hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#about" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
About
</Link>
</div>
</nav>
{/* CTA button */}
<a
href="mailto:parvagues@nech.pl?subject=Booking Request&body=Bonjour,%0D%0A%0D%0AJe souhaiterais discuter d'une possibilité de performance live coding."
className={`${styles.ctaButton} ${showInHeader ? 'scale-90' : 'scale-100'} transition-transform duration-300`}
href="/book"
className={`${styles.outlineButton} py-2 px-4 text-sm`}
>
<FaEnvelope className="inline mr-2" />
{showInHeader ? 'Invoquer' : 'Invoquer un live'}
Book
</a>
</div>
</header>
......
......@@ -75,16 +75,28 @@ export default function ParVagues({ lives }) {
// Define section content
const sections = {
potentiel: {
type: 'image',
image: '/images/parvagues/samples.png'
type: 'carousel',
images: [
'/images/parvagues/samples.png',
'/images/parvagues/code.png',
'/images/parvagues/code2.png',
'/images/parvagues/code_dense.png'
]
},
composition: {
type: 'image',
image: '/images/parvagues/gear1.jpg'
type: 'carousel',
images: [
'/images/parvagues/gear1.jpg',
'/images/parvagues/gear2.jpg',
'/images/parvagues/studio1.jpg'
]
},
performance: {
type: 'image',
image: '/images/parvagues/live.jpg'
type: 'carousel',
images: [
'/images/parvagues/live.jpg',
'/images/parvagues/code_overlay.jpg'
]
}
};
......@@ -112,53 +124,27 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
}
}, [selectedSection]);
// Carousel effect for section images
// next/pages/parvagues.js (snippet from useEffect for backgroundRef)
// Auto-advance carousel for section images
useEffect(() => {
if (!backgroundRef.current) return;
const images = backgroundRef.current.children;
if (images.length === 0) return; // Guard against no images
let index = 0;
// Initial setup for the very first image
for (let i = 0; i < images.length; i++) {
images[i].style.opacity = '0'; // Ensure all are initially transparent
}
if (images[index]) {
images[index].style.opacity = '0.7'; // Make the first one visible
}
if (sections[selectedSection]?.images?.length > 1) {
const interval = setInterval(() => {
setCurrentImageIndex(prev => (prev + 1) % sections[selectedSection].images.length);
}, 2500);
const cycle = () => {
// Current image fades out
if (images[index]) {
images[index].style.opacity = '0';
return () => clearInterval(interval);
}
}, [selectedSection, sections]);
index = (index + 1) % images.length;
// Next image fades in
if (images[index]) {
images[index].style.opacity = '0.7';
}
// Carousel navigation functions
const nextSectionImage = () => {
const imagesArray = sections[selectedSection].images;
setCurrentImageIndex(prev => (prev + 1) % imagesArray.length);
};
// Call cycle once to set the initial state correctly after a brief moment
// setTimeout(cycle, 100); // Or let the interval handle the first full cycle
const interval = setInterval(cycle, 3000); // Start cycling after 3s
return () => clearInterval(interval);
}, []); // Removed sectionImages.length from dependencies as it's not used here
useEffect(() => {
if (sectionImages.length > 1) {
const interval = setInterval(() => {
setCurrentImageIndex(prev => (prev + 1) % sectionImages.length);
}, 4000);
return () => clearInterval(interval);
}
}, [sectionImages.length]);
const prevSectionImage = () => {
const imagesArray = sections[selectedSection].images;
setCurrentImageIndex(prev => (prev === 0 ? imagesArray.length - 1 : prev - 1));
};
// Carousel effect for albums
useEffect(() => {
......@@ -226,17 +212,48 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
const sectionContent = sections[selectedSection];
if (!sectionContent) return null;
// For any section type, display the image
return (
<div className="relative w-full aspect-video rounded-lg overflow-hidden shadow-xl">
<div className="w-full rounded-lg overflow-hidden shadow-xl">
<div className="relative w-full bg-black flex items-center justify-center">
<div className="w-[30vw] h-[30vw] max-w-[30vw] max-h-[30vw] flex items-center justify-center p-4">
<div className="relative w-full h-full flex items-center justify-center">
<Image
src={sectionContent.image}
src={sectionContent.images[currentImageIndex]}
alt={selectedSection}
fill
className="object-cover"
width={1280}
height={1280}
className="w-full h-full object-contain"
priority={true}
/>
</div>
</div>
{sectionContent.images.length > 1 && (
<>
{/* Left arrow */}
<button
onClick={prevSectionImage}
className="absolute left-2 top-1/2 -translate-y-1/2 bg-black/30 hover:bg-black/50 p-2 rounded-full transition-colors"
aria-label="Image précédente"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
</button>
{/* Right arrow */}
<button
onClick={nextSectionImage}
className="absolute right-2 top-1/2 -translate-y-1/2 bg-black/30 hover:bg-black/50 p-2 rounded-full transition-colors"
aria-label="Image suivante"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</button>
</>
)}
</div>
</div>
);
};
......@@ -250,7 +267,6 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
</Head>
<div className="flex flex-col min-h-screen bg-black text-white">
{/* Apply proper sticky header */}
<ParVaguesHeader />
{/* Main content flex-auto to push footer to bottom */}
......@@ -340,26 +356,35 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
<div className={styles.splitSection}>
<div>
<div
className={`${styles.bulletPoint} cursor-pointer ${selectedSection === 'potentiel' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`${styles.bulletPoint} cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg ${selectedSection === 'potentiel' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
onClick={() => setSelectedSection('potentiel')}
>
<h3 className="text-xl font-semibold text-purple-400 mb-2">Potentiel</h3>
<h3 className="text-xl font-semibold text-purple-400 mb-2 group relative inline-block">
Potentiel
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Samples glanés et synthés SuperCollider</p>
</div>
<div
className={`${styles.bulletPoint} cursor-pointer ${selectedSection === 'composition' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`${styles.bulletPoint} cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg ${selectedSection === 'composition' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
onClick={() => setSelectedSection('composition')}
>
<h3 className="text-xl font-semibold text-purple-400 mb-2">Composition</h3>
<h3 className="text-xl font-semibold text-purple-400 mb-2 group relative inline-block">
Composition
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Code Haskell TidalCycles + input MIDI</p>
</div>
<div
className={`${styles.bulletPoint} cursor-pointer ${selectedSection === 'performance' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`${styles.bulletPoint} cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg ${selectedSection === 'performance' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
onClick={() => setSelectedSection('performance')}
>
<h3 className="text-xl font-semibold text-purple-400 mb-2">Performance</h3>
<h3 className="text-xl font-semibold text-purple-400 mb-2 group relative inline-block">
Performance
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Performance live avec improvisation au contrôleur MIDI</p>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment