Skip to content

Commit b203960

Browse files
committed
feat(demo): add interactive scroll animation guide for demo 1 immersive modal
- Add scroll animation that guides users through demo steps - Implement automatic highlighting of next execute button - Add visual indicators with pulsing rings and glowing effects - Include progress indicator showing 'Guiding to next step...' - Add celebration animation on demo completion - Enhance user experience with smooth scrolling transitions - Auto-cleanup animations after 3 seconds to prevent conflicts
1 parent 0862cfa commit b203960

40 files changed

+2291
-738
lines changed

COMMANDS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,5 @@ npm run clean # Clean up cache
177177

178178
**🚀 Happy coding!**
179179

180+
181+

app/demos/page.tsx

Lines changed: 120 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { Footer } from '@/components/layout/Footer';
77
import { NexusPrime } from '@/components/layout/NexusPrime';
88
import { EscrowProvider } from '@/contexts/EscrowContext';
99
import { WalletProvider } from '@/contexts/WalletContext';
10+
import { AuthProvider } from '@/contexts/AuthContext';
1011
import { Providers } from '@/components/Providers';
1112
import { TransactionProvider } from '@/contexts/TransactionContext';
1213
import { ToastProvider } from '@/contexts/ToastContext';
1314
import { useGlobalWallet } from '@/contexts/WalletContext';
15+
import { useAuth } from '@/contexts/AuthContext';
1416
import { HelloMilestoneDemo } from '@/components/demos/HelloMilestoneDemo';
1517
import { MilestoneVotingDemo } from '@/components/demos/MilestoneVotingDemo';
1618
import { DisputeResolutionDemo } from '@/components/demos/DisputeResolutionDemo';
@@ -19,6 +21,9 @@ import { OnboardingOverlay } from '@/components/OnboardingOverlay';
1921
import { ImmersiveDemoModal } from '@/components/ui/ImmersiveDemoModal';
2022
import { TechTreeModal } from '@/components/ui/TechTreeModal';
2123
import { ToastContainer } from '@/components/ui/Toast';
24+
import { AuthBanner } from '@/components/ui/AuthBanner';
25+
import { AuthModal } from '@/components/ui/AuthModal';
26+
import { UserProfile } from '@/components/ui/UserProfile';
2227
import Image from 'next/image';
2328
import { nexusCodex } from '@/lib/newsData';
2429

@@ -36,10 +41,12 @@ const DemoSelector = ({
3641
activeDemo,
3742
setActiveDemo,
3843
setShowImmersiveDemo,
44+
isConnected,
3945
}: {
4046
activeDemo: string;
4147
setActiveDemo: (demo: string) => void;
4248
setShowImmersiveDemo: (show: boolean) => void;
49+
isConnected: boolean;
4350
}) => {
4451
// Clap system with localStorage persistence
4552
const [demoClaps, setDemoClaps] = useState<Record<string, number>>(() => {
@@ -335,20 +342,33 @@ const DemoSelector = ({
335342
<button
336343
onClick={e => {
337344
e.stopPropagation();
338-
setShowImmersiveDemo(true);
345+
if (isConnected) {
346+
setShowImmersiveDemo(true);
347+
}
339348
}}
340-
className='relative px-8 py-4 font-bold rounded-xl transition-all duration-500 transform hover:scale-110 hover:rotate-1 shadow-2xl hover:shadow-brand-500/50 border-2 bg-gradient-to-r from-brand-500 via-accent-500 to-brand-400 hover:from-brand-600 hover:via-accent-600 hover:to-brand-500 text-white border-white/30 hover:border-white/60 text-lg'
349+
disabled={!isConnected}
350+
className={`relative px-8 py-4 font-bold rounded-xl transition-all duration-500 transform shadow-2xl border-2 text-lg ${
351+
isConnected
352+
? 'hover:scale-110 hover:rotate-1 hover:shadow-brand-500/50 bg-gradient-to-r from-brand-500 via-accent-500 to-brand-400 hover:from-brand-600 hover:via-accent-600 hover:to-brand-500 text-white border-white/30 hover:border-white/60'
353+
: 'bg-gradient-to-r from-gray-600 via-gray-700 to-gray-600 text-gray-400 border-gray-600 cursor-not-allowed blur-sm opacity-60'
354+
}`}
341355
>
342356
{/* Button Content */}
343357
<div className='flex items-center'>
344358
<div className='flex flex-col'>
345-
<span className='text-lg font-bold'>LAUNCH DEMO</span>
346-
<span className='text-xs opacity-80'>Prepare for AWESOMENESS!</span>
359+
<span className='text-lg font-bold'>
360+
{isConnected ? 'LAUNCH DEMO' : 'CONNECT WALLET'}
361+
</span>
362+
<span className='text-xs opacity-80'>
363+
{isConnected ? 'Prepare for AWESOMENESS!' : 'Required to launch demo'}
364+
</span>
347365
</div>
348366
</div>
349367

350-
{/* Hover Effects */}
351-
<div className='absolute inset-0 bg-gradient-to-r from-white/0 via-white/10 to-white/0 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300'></div>
368+
{/* Hover Effects - Only show when connected */}
369+
{isConnected && (
370+
<div className='absolute inset-0 bg-gradient-to-r from-white/0 via-white/10 to-white/0 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300'></div>
371+
)}
352372
</button>
353373

354374
{/* Rotating Nexus Logo */}
@@ -383,6 +403,7 @@ const DemoSelector = ({
383403

384404
function DemosPageContent() {
385405
const { isConnected } = useGlobalWallet();
406+
const { isAuthenticated, user } = useAuth();
386407
const [activeDemo, setActiveDemo] = useState('hello-milestone');
387408
const [walletSidebarOpen, setWalletSidebarOpen] = useState(false);
388409
const [walletExpanded, setWalletExpanded] = useState(false);
@@ -399,6 +420,11 @@ function DemosPageContent() {
399420
const [loadingProgress, setLoadingProgress] = useState(0);
400421
const [showImmersiveDemo, setShowImmersiveDemo] = useState(false);
401422
const [showTechTree, setShowTechTree] = useState(false);
423+
424+
// Authentication modals
425+
const [showAuthModal, setShowAuthModal] = useState(false);
426+
const [authModalMode, setAuthModalMode] = useState<'signup' | 'signin'>('signup');
427+
const [showUserProfile, setShowUserProfile] = useState(false);
402428

403429
// Preloader effect - only on first load
404430
useEffect(() => {
@@ -444,18 +470,45 @@ function DemosPageContent() {
444470
}
445471
};
446472

473+
const handleOpenUserProfile = () => {
474+
setShowUserProfile(true);
475+
};
476+
447477
window.addEventListener('walletSidebarToggle', handleWalletSidebarToggle as EventListener);
478+
window.addEventListener('openUserProfile', handleOpenUserProfile);
448479
return () => {
449480
window.removeEventListener('walletSidebarToggle', handleWalletSidebarToggle as EventListener);
481+
window.removeEventListener('openUserProfile', handleOpenUserProfile);
450482
};
451483
}, []);
452484

485+
// Authentication handlers
486+
const handleSignUpClick = () => {
487+
setAuthModalMode('signup');
488+
setShowAuthModal(true);
489+
};
490+
491+
const handleSignInClick = () => {
492+
setAuthModalMode('signin');
493+
setShowAuthModal(true);
494+
};
495+
496+
const handleUserProfileClick = () => {
497+
setShowUserProfile(true);
498+
};
499+
453500
return (
454501
<EscrowProvider>
455502
<div className='min-h-screen bg-gradient-to-br from-neutral-900 via-brand-900 to-neutral-900 relative overflow-hidden'>
456503
{/* Header */}
457504
<Header />
458505

506+
{/* Authentication Banner */}
507+
<AuthBanner
508+
onSignUpClick={handleSignUpClick}
509+
onSignInClick={handleSignInClick}
510+
/>
511+
459512
{/* Animated background elements */}
460513
<div className='absolute inset-0 opacity-20 bg-gradient-to-r from-brand-500/10 via-transparent to-accent-500/10'></div>
461514

@@ -630,7 +683,7 @@ function DemosPageContent() {
630683
<br />
631684

632685
<p className='text-xl text-white/80 max-w-3xl mx-auto mb-6'>
633-
Master the art of trustless work with our hilarious demo suite on Stellar
686+
Master the art of trustless work with our demo suite on Stellar
634687
blockchain
635688
</p>
636689

@@ -654,12 +707,46 @@ function DemosPageContent() {
654707
</button>
655708

656709
<button
657-
onClick={() => setShowTechTree(true)}
658-
className='px-8 py-4 bg-gradient-to-r from-brand-500/20 to-accent-500/20 hover:from-brand-800/50 hover:to-accent-800/50 text-white font-bold rounded-xl transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-xl border-2 border-white/20 hover:border-white/40 flex items-center space-x-3'
710+
onClick={() => isConnected && setShowTechTree(true)}
711+
disabled={!isConnected}
712+
className={`px-8 py-4 font-bold rounded-xl transition-all duration-300 flex items-center space-x-3 ${
713+
isConnected
714+
? 'bg-gradient-to-r from-brand-500/20 to-accent-500/20 hover:from-brand-800/50 hover:to-accent-800/50 text-white transform hover:scale-105 shadow-lg hover:shadow-xl border-2 border-white/20 hover:border-white/40'
715+
: 'bg-gradient-to-r from-gray-600/20 to-gray-700/20 text-gray-400 border-gray-600/30 cursor-not-allowed blur-[0.5px] opacity-70'
716+
}`}
717+
title={!isConnected ? 'Connect wallet to explore the tech tree' : ''}
659718
>
660-
<span>Tech Tree Explorer</span>
661-
<span className='text-xl'>🌳</span>
719+
<span>Trustless Work Tech Tree</span>
720+
<span className='text-xl'>
721+
<Image src='/images/icons/demos.png' alt='Trustless Work Tech Tree' width={50} height={20} />
722+
</span>
723+
{!isConnected && (
724+
<span className='absolute -top-1 -right-1 text-xs bg-gray-600 text-gray-300 px-1 rounded-full'>
725+
🔒
726+
</span>
727+
)}
662728
</button>
729+
730+
<a
731+
href={isConnected ? '/mini-games' : '#'}
732+
onClick={(e) => !isConnected && e.preventDefault()}
733+
className={`px-8 py-4 font-bold rounded-xl transition-all duration-300 flex items-center space-x-3 relative ${
734+
isConnected
735+
? 'bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white transform hover:scale-105 shadow-lg hover:shadow-xl border-2 border-white/20 hover:border-white/40'
736+
: 'bg-gradient-to-r from-gray-600/20 to-gray-700/20 text-gray-400 border-gray-600/30 cursor-not-allowed blur-[0.5px] opacity-70'
737+
}`}
738+
title={!isConnected ? 'Connect wallet to access the Web3 playground' : ''}
739+
>
740+
<span>Nexus Web3 Playground</span>
741+
<span className='text-xl'>
742+
<Image src='/images/icons/console.png' alt='Nexus Web3 Playground' width={50} height={20} />
743+
</span>
744+
{!isConnected && (
745+
<span className='absolute -top-1 -right-1 text-xs bg-gray-600 text-gray-300 px-1 rounded-full'>
746+
🔒
747+
</span>
748+
)}
749+
</a>
663750
</div>
664751
</div>
665752

@@ -940,6 +1027,7 @@ function DemosPageContent() {
9401027
activeDemo={activeDemo}
9411028
setActiveDemo={setActiveDemo}
9421029
setShowImmersiveDemo={setShowImmersiveDemo}
1030+
isConnected={isConnected}
9431031
/>
9441032
</div>
9451033
</section>
@@ -1169,19 +1257,34 @@ function DemosPageContent() {
11691257

11701258
{/* Tech Tree Modal */}
11711259
<TechTreeModal isOpen={showTechTree} onClose={() => setShowTechTree(false)} />
1260+
1261+
{/* Authentication Modal */}
1262+
<AuthModal
1263+
isOpen={showAuthModal}
1264+
onClose={() => setShowAuthModal(false)}
1265+
mode={authModalMode}
1266+
/>
1267+
1268+
{/* User Profile Modal */}
1269+
<UserProfile
1270+
isOpen={showUserProfile}
1271+
onClose={() => setShowUserProfile(false)}
1272+
/>
11721273
</EscrowProvider>
11731274
);
11741275
}
11751276

11761277
export default function DemosPage() {
11771278
return (
11781279
<WalletProvider>
1179-
<ToastProvider>
1180-
<TransactionProvider>
1181-
<DemosPageContent />
1182-
<ToastContainer />
1183-
</TransactionProvider>
1184-
</ToastProvider>
1280+
<AuthProvider>
1281+
<ToastProvider>
1282+
<TransactionProvider>
1283+
<DemosPageContent />
1284+
<ToastContainer />
1285+
</TransactionProvider>
1286+
</ToastProvider>
1287+
</AuthProvider>
11851288
</WalletProvider>
11861289
);
11871290
}

app/globals.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,22 @@ body {
105105
animation: slideInUp 0.6s ease-out;
106106
}
107107

108+
/* Slide In Left Animation */
109+
@keyframes slideInLeft {
110+
from {
111+
transform: translateX(-100%);
112+
opacity: 0;
113+
}
114+
to {
115+
transform: translateX(0);
116+
opacity: 1;
117+
}
118+
}
119+
120+
.animate-slideInLeft {
121+
animation: slideInLeft 0.8s ease-out;
122+
}
123+
108124
/* Fade In Up Animation */
109125
@keyframes fadeInUp {
110126
from {

app/mini-games/page.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
import MiniGameStore from '@/components/games/MiniGameStore';
2+
import { WalletProvider } from '@/contexts/WalletContext';
3+
import { AuthProvider } from '@/contexts/AuthContext';
4+
import { ToastProvider } from '@/contexts/ToastContext';
5+
import { TransactionProvider } from '@/contexts/TransactionContext';
6+
import { ToastContainer } from '@/components/ui/Toast';
27

38
export default function MiniGamesPage() {
4-
return <MiniGameStore />;
9+
return (
10+
<WalletProvider>
11+
<AuthProvider>
12+
<ToastProvider>
13+
<TransactionProvider>
14+
<MiniGameStore />
15+
<ToastContainer />
16+
</TransactionProvider>
17+
</ToastProvider>
18+
</AuthProvider>
19+
</WalletProvider>
20+
);
521
}

components/OnboardingOverlay.tsx

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -581,20 +581,39 @@ export const OnboardingOverlay = ({
581581
{/* Demo Tabs */}
582582
<div className='bg-white/5 p-4 border-b border-white/10'>
583583
<div className='flex flex-wrap gap-2'>
584-
{demoTabs.map(tab => (
585-
<button
586-
key={tab.id}
587-
onClick={() => handleTabChange(tab.id)}
588-
className={`px-4 py-2 rounded-lg border transition-all duration-300 flex items-center space-x-2 ${
589-
activeTab === tab.id
590-
? `bg-gradient-to-r ${tab.color} text-white border-white/50 shadow-lg`
591-
: 'bg-white/5 border-white/20 text-white/70 hover:bg-white/10 hover:border-white/30'
592-
}`}
593-
>
594-
<span className='text-lg'>{tab.icon}</span>
595-
<span className='font-medium'>{tab.title}</span>
596-
</button>
597-
))}
584+
{demoTabs.map(tab => {
585+
const isFirstDemo = tab.id === 'hello-milestone';
586+
const isDisabled = !isFirstDemo;
587+
588+
return (
589+
<button
590+
key={tab.id}
591+
onClick={() => !isDisabled && handleTabChange(tab.id)}
592+
disabled={isDisabled}
593+
className={`px-4 py-2 rounded-lg border transition-all duration-300 flex items-center space-x-2 relative ${
594+
isDisabled
595+
? 'bg-gray-600/20 border-gray-600/30 text-gray-400 cursor-not-allowed blur-sm opacity-50'
596+
: activeTab === tab.id
597+
? `bg-gradient-to-r ${tab.color} text-white border-white/50 shadow-lg`
598+
: 'bg-white/5 border-white/20 text-white/70 hover:bg-white/10 hover:border-white/30'
599+
}`}
600+
title={isDisabled ? 'Complete the first demo to unlock this tutorial' : ''}
601+
>
602+
<span className='text-lg'>{tab.icon}</span>
603+
<span className='font-medium'>{tab.title}</span>
604+
{isDisabled && (
605+
<span className='absolute -top-1 -right-1 text-xs bg-gray-600 text-gray-300 px-1 rounded-full'>
606+
🔒
607+
</span>
608+
)}
609+
</button>
610+
);
611+
})}
612+
</div>
613+
<div className='mt-2 text-center'>
614+
<p className='text-xs text-gray-400'>
615+
💡 Complete "Baby Steps" to unlock advanced tutorials
616+
</p>
598617
</div>
599618
</div>
600619

0 commit comments

Comments
 (0)