8 Commits

Author SHA1 Message Date
3774b119af Merge version_3 into main
Merge version_3 into main
2026-06-07 23:06:51 +00:00
d15aad921a Update src/app/page.tsx 2026-06-07 23:06:48 +00:00
5eb66fbf34 Merge version_3 into main
Merge version_3 into main
2026-06-07 23:06:27 +00:00
f67c97c1fd Update src/app/page.tsx 2026-06-07 23:06:21 +00:00
4456a0bfb4 Merge version_2 into main
Merge version_2 into main
2026-06-07 23:01:21 +00:00
3047f1cbcf Merge version_2 into main
Merge version_2 into main
2026-06-07 23:00:30 +00:00
0d607bba63 Merge version_2 into main
Merge version_2 into main
2026-06-07 22:59:44 +00:00
e3fd23e884 Merge version_2 into main
Merge version_2 into main
2026-06-07 22:59:15 +00:00

View File

@@ -5,37 +5,74 @@ import React, { useState, useMemo } from "react";
import ReactLenis from "lenis/react"; import ReactLenis from "lenis/react";
import HeroSplitDualMedia from '@/components/sections/hero/HeroSplitDualMedia'; import HeroSplitDualMedia from '@/components/sections/hero/HeroSplitDualMedia';
// Move the random generation outside the component to ensure purity during render // Helper to generate styles for floating elements (hearts, balloons, confetti)
const generateHeartStyles = () => { const generateFloatingStyles = (count: number, type: 'heart' | 'balloon' | 'confetti', scaleMin: number, scaleMax: number, durationMin: number, durationMax: number, delayMin: number, delayMax: number) => {
return Array.from({ length: 30 }).map(() => ({ return Array.from({ length: count }).map((_, i) => ({
type,
left: `${Math.random() * 100}vw`, left: `${Math.random() * 100}vw`,
animationDelay: `${Math.random() * 5}s`, animationDelay: `${delayMin + Math.random() * (delayMax - delayMin)}s`,
animationDuration: `${5 + Math.random() * 5}s`, animationDuration: `${durationMin + Math.random() * (durationMax - durationMin)}s`,
transform: `scale(${0.5 + Math.random()})` transform: `scale(${scaleMin + Math.random() * (scaleMax - scaleMin)})`,
zIndex: Math.floor(Math.random() * 10) + 1, // Random z-index for depth
})); }));
}; };
const initialHeartStyles = generateHeartStyles(); // Generate once when module loads const getEmojiForType = (type: 'heart' | 'balloon' | 'confetti') => {
if (type === 'heart') return '❤️';
if (type === 'balloon') return '🎈';
const confettiEmojis = ['✨', '🥳', '🎉'];
return confettiEmojis[Math.floor(Math.random() * confettiEmojis.length)];
};
const initialFloatingElements = {
hearts: generateFloatingStyles(50, 'heart', 0.5, 1.5, 5, 10, 0, 5),
balloons: generateFloatingStyles(30, 'balloon', 0.8, 1.2, 7, 12, 0, 7),
confetti: generateFloatingStyles(100, 'confetti', 0.3, 0.8, 3, 7, 0, 4),
};
const FloatingElements = () => {
const elements = useMemo(() => {
return [
...initialFloatingElements.hearts,
...initialFloatingElements.balloons,
...initialFloatingElements.confetti,
];
}, []);
return (
<>
{elements.map((style, i) => (
<div
key={i}
className="absolute opacity-0 animate-floating"
style={{
left: style.left,
animationDelay: style.animationDelay,
animationDuration: style.animationDuration,
transform: style.transform,
zIndex: style.zIndex,
fontSize: style.type === 'heart' ? '2rem' : (style.type === 'balloon' ? '2.5rem' : '1.5rem')
}}
>
{getEmojiForType(style.type)}
</div>
))}
</>
);
};
const CelebrationOverlay = () => { const CelebrationOverlay = () => {
const heartStyles = useMemo(() => initialHeartStyles, []); // Reference the pre-generated styles
const hearts = heartStyles.map((style, i) => (
<div
key={i}
className="absolute text-pink-500 text-3xl opacity-0 animate-heart-fall"
style={style}
>
</div>
));
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-pink-100 bg-opacity-90 overflow-hidden"> <div className="fixed inset-0 z-50 flex items-center justify-center bg-pink-100 bg-opacity-90 overflow-hidden">
<div className="relative text-center text-pink-700 text-5xl font-bold p-8 animate-fade-in"> <div className="relative text-center text-pink-700 text-5xl font-bold p-8 animate-fade-in">
I Love You Bisma <img
src="https://imagedelivery.net/qN7d-a1E2_g_t-wwxG89gQ/cb330456-e41c-4384-a82f-2f8021c33c00/public" // Placeholder engagement ring
alt="USA-style engagement ring"
className="mx-auto mb-8 w-48 h-48 object-contain animate-ring-pop"
/>
I love you Bisma
<div className="absolute top-0 left-0 w-full h-full pointer-events-none"> <div className="absolute top-0 left-0 w-full h-full pointer-events-none">
{hearts} <FloatingElements />
</div> </div>
</div> </div>
</div> </div>
@@ -44,8 +81,7 @@ const CelebrationOverlay = () => {
export default function LandingPage() { export default function LandingPage() {
const noMessages = [ const noMessages = [
"Are you sure, Bisma? Think about our future... 🫠", "Please reconsider, my love. My heart aches at the thought. 💔", "Don't say no! We're meant to be. This isn't a game. 😭", "Just one more chance... Say yes! 🙏", "My world stops without you. Please, Bisma. Yes? ✨" "Please kar lo na 🥺", "Main tum se bohat pyar karta hoon ❤️", "Ab to yes kar do na 🥹", "Please Bisma, maan jao na ❤️", "Mere liye yes kar do 💕", "Last time bol raha hoon, yes kar do ❤️"];
];
const [noClickCount, setNoClickCount] = useState(0); const [noClickCount, setNoClickCount] = useState(0);
const [showCelebration, setShowCelebration] = useState(false); const [showCelebration, setShowCelebration] = useState(false);
@@ -57,36 +93,48 @@ export default function LandingPage() {
setNoClickCount((prevCount) => prevCount + 1); setNoClickCount((prevCount) => prevCount + 1);
}; };
const currentDescription = noClickCount < 5 const initialProposalDescription = "You are the most beautiful, kind, and brilliant person I know. My love for you grows with each passing moment, and I can't imagine a future without you by my side. Will you make me the happiest man alive?";
? "My dearest Bisma, from the moment I met you, my world changed. Every day with you is a joy, an adventure, and a blessing. You are the most beautiful, kind, and brilliant person I know. My love for you grows with each passing moment, and I can't imagine a future without you by my side. Let's start our forever now."
const currentHeroDescription = noClickCount === 0
? initialProposalDescription
: noMessages[Math.min(noClickCount - 1, noMessages.length - 1)]; : noMessages[Math.min(noClickCount - 1, noMessages.length - 1)];
const buttons = noClickCount < 5 const buttons = noClickCount < 6
? [ ? [
{ text: "Yes", onClick: handleYesClick }, { text: "Yes", onClick: handleYesClick },
{ text: "No", onClick: handleNoClick } { text: "No", onClick: handleNoClick }
] ]
: [ : [
{ text: "Yes ❤️", onClick: handleYesClick }, { text: "Yes ❤️", onClick: handleYesClick } { text: "Yes ❤️", onClick: handleYesClick },
{ text: "Yes ❤️", onClick: handleYesClick }
]; ];
// Tailwind keyframes for hearts and fade-in // Tailwind keyframes for floating elements and fade-in
const globalStyles = ` const globalStyles = `
@keyframes heart-fall { @keyframes floating {
0% { transform: translateY(-100vh) rotate(0deg) scale(0); opacity: 0; } 0% { transform: translateY(-100vh) scale(0) rotate(0deg); opacity: 0; }
10% { opacity: 1; } 10% { opacity: 1; transform: translateY(-80vh) scale(1) rotate(20deg); }
100% { transform: translateY(100vh) rotate(360deg) scale(1.5); opacity: 0; } 50% { opacity: 1; transform: translateY(0vh) scale(1.2) rotate(-20deg); }
100% { transform: translateY(100vh) scale(0) rotate(0deg); opacity: 0; }
} }
@keyframes fade-in { @keyframes fade-in {
from { opacity: 0; transform: translateY(20px); } from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); } to { opacity: 1; transform: translateY(0); }
} }
.animate-heart-fall { @keyframes ring-pop {
animation: heart-fall linear infinite; 0% { transform: scale(0); opacity: 0; }
50% { transform: scale(1.2); opacity: 1; }
100% { transform: scale(1); opacity: 1; }
}
.animate-floating {
animation: floating linear infinite;
} }
.animate-fade-in { .animate-fade-in {
animation: fade-in 1s ease-out forwards; animation: fade-in 1s ease-out forwards;
} }
.animate-ring-pop {
animation: ring-pop 0.8s ease-out forwards;
}
html, body, #__next { html, body, #__next {
height: 100%; height: 100%;
margin: 0; margin: 0;
@@ -116,26 +164,26 @@ export default function LandingPage() {
<HeroSplitDualMedia <HeroSplitDualMedia
background={{ variant: "plain" }} background={{ variant: "plain" }}
title="Bisma, will you marry me?" title="Bisma, will you marry me?"
description={currentDescription} description={currentHeroDescription}
tag="A Lifetime Together" tag="My Dearest Love"
buttons={buttons} buttons={buttons}
mediaItems={[ mediaItems={[
{ imageSrc: '', imageAlt: '' }, { imageSrc: 'https://imagedelivery.net/qN7d-a1E2_g_t-wwxG89gQ/cb330456-e41c-4384-a82f-2f8021c33c00/public?_wi=1', imageAlt: 'Diamond ring placeholder' },
{ imageSrc: '', imageAlt: '' }, { imageSrc: 'https://imagedelivery.net/qN7d-a1E2_g_t-wwxG89gQ/cb330456-e41c-4384-a82f-2f8021c33c00/public?_wi=2', imageAlt: 'Diamond ring placeholder' },
]} ]}
mediaAnimation="none" mediaAnimation="none"
rating={0} rating={0}
ratingText="" ratingText=""
containerClassName="p-8 max-w-3xl text-center" containerClassName="p-8 max-w-3xl text-center"
titleClassName="text-5xl font-extrabold mb-4 text-pink-800" titleClassName="text-5xl md:text-6xl lg:text-7xl font-extrabold mb-4 text-pink-800"
descriptionClassName="text-xl text-pink-700 mb-8" descriptionClassName="text-xl md:text-2xl text-pink-700 mb-8"
buttonContainerClassName="flex justify-center gap-4" buttonContainerClassName="flex justify-center gap-4 mt-8"
buttonClassName="bg-pink-600 hover:bg-pink-700 text-white font-bold py-3 px-6 rounded-full shadow-lg transition duration-300 ease-in-out" buttonClassName="bg-pink-600 hover:bg-pink-700 text-white font-bold py-3 px-6 rounded-full shadow-lg transition duration-300 ease-in-out text-lg"
tagClassName="text-pink-500 mb-2" tagClassName="text-pink-500 mb-2 font-medium"
/> />
</div> </div>
)} )}
</ReactLenis> </ReactLenis>
</ThemeProvider> </ThemeProvider>
); );
} }