Skip to content

Commit a3c7b70

Browse files
committed
feat(demo-stats): integrate Firebase demo completion tracking
- Replace localStorage demo completion tracking with Firebase integration - Update HelloMilestoneDemo to call markDemoComplete from useDemoStats hook - Update demos page to use Firebase demo stats instead of hardcoded values - Ensure completion counts increase correctly when demo is completed multiple times - Add proper Firebase demo stats service integration
1 parent 197b2f7 commit a3c7b70

File tree

3 files changed

+21
-125
lines changed

3 files changed

+21
-125
lines changed

app/demos/page.tsx

Lines changed: 16 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { AuthModal } from '@/components/ui/AuthModal';
3030
import { UserProfile } from '@/components/ui/UserProfile';
3131
import { AccountStatusIndicator } from '@/components/ui/AccountStatusIndicator';
3232
import Image from 'next/image';
33-
import { nexusCodex } from '@/lib/newsData';
33+
import { useDemoStats } from '@/hooks/useDemoStats';
3434

3535
// Demo Selection Component
3636
interface Demo {
@@ -54,92 +54,27 @@ const DemoSelector = ({
5454
isConnected: boolean;
5555
}) => {
5656
const { getCompletedDemos } = useAccount();
57-
// Clap system with localStorage persistence
58-
const [demoClaps, setDemoClaps] = useState<Record<string, number>>(() => {
59-
if (typeof window !== 'undefined') {
60-
const saved = localStorage.getItem('demoClaps');
61-
return saved
62-
? JSON.parse(saved)
63-
: {
64-
'hello-milestone': 24,
65-
'milestone-voting': 18,
66-
'dispute-resolution': 12,
67-
'micro-marketplace': 31,
68-
};
69-
}
70-
return {
71-
'hello-milestone': 24,
72-
'milestone-voting': 18,
73-
'dispute-resolution': 12,
74-
'micro-marketplace': 31,
75-
};
76-
});
77-
const [userClapped, setUserClapped] = useState<Record<string, boolean>>(() => {
78-
if (typeof window !== 'undefined') {
79-
const saved = localStorage.getItem('userClapped');
80-
return saved
81-
? JSON.parse(saved)
82-
: {
83-
'hello-milestone': false,
84-
'milestone-voting': false,
85-
'dispute-resolution': false,
86-
'micro-marketplace': false,
87-
};
88-
}
89-
return {
90-
'hello-milestone': false,
91-
'milestone-voting': false,
92-
'dispute-resolution': false,
93-
'micro-marketplace': false,
94-
};
95-
});
96-
97-
// Simulated completion counts for demos
98-
const [demoCompletions, setDemoCompletions] = useState<Record<string, number>>(() => {
99-
if (typeof window !== 'undefined') {
100-
const saved = localStorage.getItem('demoCompletions');
101-
return saved
102-
? JSON.parse(saved)
103-
: {
104-
'hello-milestone': 42,
105-
'milestone-voting': 28,
106-
'dispute-resolution': 19,
107-
'micro-marketplace': 35,
108-
};
109-
}
110-
return {
111-
'hello-milestone': 42,
112-
'milestone-voting': 28,
113-
'dispute-resolution': 19,
114-
'micro-marketplace': 35,
115-
};
116-
});
117-
118-
const handleClap = (demoId: string) => {
119-
if (userClapped[demoId]) return; // User already clapped
57+
const { demoStats, clapDemo, isLoading: statsLoading } = useDemoStats();
12058

121-
const newClaps = { ...demoClaps, [demoId]: demoClaps[demoId] + 1 };
122-
const newUserClapped = { ...userClapped, [demoId]: true };
123-
124-
setDemoClaps(newClaps);
125-
setUserClapped(newUserClapped);
126-
127-
// Save to localStorage
128-
if (typeof window !== 'undefined') {
129-
localStorage.setItem('demoClaps', JSON.stringify(newClaps));
130-
localStorage.setItem('userClapped', JSON.stringify(newUserClapped));
131-
}
59+
const handleClap = async (demoId: string) => {
60+
const demoName = demos.find(d => d.id === demoId)?.title || demoId;
61+
await clapDemo(demoId, demoName);
13262
};
13363

13464
const getClapStats = (demoId: string) => {
135-
const claps = demoClaps[demoId];
136-
const hasClapped = userClapped[demoId];
137-
const completions = demoCompletions[demoId];
65+
const stats = demoStats[demoId];
66+
if (!stats) {
67+
return {
68+
claps: 0,
69+
hasClapped: false,
70+
completions: 0,
71+
};
72+
}
13873

13974
return {
140-
claps: claps,
141-
hasClapped: hasClapped,
142-
completions: completions,
75+
claps: stats.totalClaps,
76+
hasClapped: stats.hasUserClapped,
77+
completions: stats.totalCompletions,
14378
};
14479
};
14580

components/demos/HelloMilestoneDemo.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useTransactionHistory } from '@/contexts/TransactionContext';
99
import ConfettiAnimation from '@/components/ui/ConfettiAnimation';
1010
import { TypeWriter, ProcessExplanation } from '@/components/ui/TypeWriter';
1111
import { DemoCompletionHistory } from '@/components/ui/DemoCompletionHistory';
12+
import { useDemoStats } from '@/hooks/useDemoStats';
1213
import { useDemoCompletionHistory } from '@/hooks/useDemoCompletionHistory';
1314
import Image from 'next/image';
1415
import {
@@ -47,6 +48,7 @@ export const HelloMilestoneDemo = () => {
4748
const { addToast } = useToast();
4849
const { addTransaction, updateTransaction } = useTransactionHistory();
4950
const { addCompletion, getDemoHistory, getTotalPointsEarned, getBestScore, getCompletionCount } = useDemoCompletionHistory();
51+
const { markDemoComplete } = useDemoStats();
5052
const [currentStep, setCurrentStep] = useState(0);
5153
const [contractId, setContractId] = useState<string>('');
5254
const [escrowData, setEscrowData] = useState<any>(null);
@@ -548,6 +550,9 @@ export const HelloMilestoneDemo = () => {
548550

549551
// Complete the demo in the account system
550552
await completeDemo('hello-milestone', score);
553+
554+
// Mark demo complete in Firebase stats
555+
await markDemoComplete('hello-milestone', 'Baby Steps to Riches', completionTime);
551556
} catch (error) {
552557
console.error('Failed to complete demo:', error);
553558
}

components/ui/WalletSidebar.tsx

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -971,50 +971,6 @@ export const WalletSidebar = ({ isOpen, onToggle, showBanner = false }: WalletSi
971971
</>
972972
)}
973973

974-
{/* Navigation Buttons - Matching Main Menu - Always show but with different states */}
975-
{!isOpen && (
976-
<>
977-
{/* Demos Button */}
978-
{isConnected ? (
979-
<a
980-
href='/demos'
981-
className='p-3 bg-gradient-to-br from-cyan-500 to-blue-600 hover:from-cyan-600 hover:to-blue-700 text-white rounded-lg shadow-lg transition-all duration-300 transform hover:scale-105 group'
982-
title='Demos'
983-
>
984-
<div className='flex items-center space-x-2'>
985-
<Image
986-
src='/images/icons/demos.png'
987-
alt='Demos'
988-
width={20}
989-
height={20}
990-
className='w-5 h-5 group-hover:animate-bounce'
991-
/>
992-
<span className='text-sm font-medium hidden lg:block'>Demos</span>
993-
</div>
994-
</a>
995-
) : (
996-
<div
997-
className='p-3 bg-gray-500/30 rounded-lg shadow-lg relative cursor-not-allowed blur-[1px] opacity-70'
998-
title='Connect wallet to access Demos'
999-
>
1000-
<div className='flex items-center space-x-2'>
1001-
<Image
1002-
src='/images/icons/demos.png'
1003-
alt='Demos'
1004-
width={20}
1005-
height={20}
1006-
className='w-5 h-5'
1007-
/>
1008-
<span className='text-sm font-medium hidden lg:block text-gray-400'>Demos</span>
1009-
<div className='absolute top-1 right-1'>
1010-
<span className='text-xs bg-red-500 text-white px-1.5 py-0.5 rounded-full'>🔒</span>
1011-
</div>
1012-
</div>
1013-
</div>
1014-
)}
1015-
1016-
</>
1017-
)}
1018974
</div>
1019975

1020976
{/* Wallet Connection Banner */}

0 commit comments

Comments
 (0)