Skip to content

Commit d607e37

Browse files
committed
Merge branch 'main' of github.com:efdevcon/monorepo
2 parents 349fa2a + d86799c commit d607e37

7 files changed

Lines changed: 1156 additions & 72 deletions

File tree

devconnect-app/scripts/fetch-quests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ async function saveQuests(data: ApiResponse): Promise<void> {
118118
const { group, ...questWithoutGroup } = quest;
119119
return {
120120
...questWithoutGroup,
121+
action: quest.action as Quest['action'],
122+
conditionType: quest.conditionType as Quest['conditionType'],
121123
groupId,
122124
districtId,
123125
};

devconnect-app/src/app/quests/AppShowcaseDetail.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,30 @@ import Image from 'next/image';
77
import { districtsData } from '@/data/districts';
88
import { questsData } from '@/data/quests';
99
import { supportersData } from '@/data/supporters';
10-
import type { Quest, QuestGroup } from '@/types';
10+
import type { Quest, QuestAction, QuestGroup } from '@/types';
1111
import cn from 'classnames';
1212
import { SupporterInfo } from '@/app/map/venue-map/components/SupporterInfo';
1313
import { executeQuestAction } from '@/utils/quest-actions';
1414
import { useWalletManager } from '@/hooks/useWalletManager';
1515

1616
// Quest icons mapping based on action type
17-
const getQuestIcon = (action: string) => {
18-
const iconMap: Record<string, string> = {
17+
const getQuestIcon = (action: QuestAction) => {
18+
const iconMap: Record<QuestAction, string> = {
1919
'connect-wallet': '/images/icons/ticket.svg',
20-
'associate-ticket': '/images/icons/heart-outline.svg',
20+
'associate-ticket': '/images/icons/ticket.svg',
2121
'setup-profile': '/images/icons/map.svg',
22-
'visit-link': '/images/icons/qrcode-scan.svg',
22+
'visit-link': '/images/icons/cash-plus.svg',
2323
'mini-quiz': '/images/icons/cash-plus.svg',
2424
'verify-payment': '/images/icons/cash-plus.svg',
2525
'claim-poap': '/images/icons/check-circle.svg',
2626
'verify-basename': '/images/icons/check-circle.svg',
27+
'favorite-schedule': '/images/icons/heart-outline.svg',
28+
'explore-map': '/images/icons/map.svg',
29+
'try-qr': '/images/icons/qrcode-scan.svg',
30+
'verify-ens': '/images/icons/cash-plus.svg',
31+
todo: '/images/icons/default-quest.svg',
32+
'verify-balance': '/images/icons/cash-plus.svg',
33+
'': '/images/icons/default-quest.svg',
2734
};
2835

2936
return iconMap[action] || '/images/icons/default-quest.svg';
@@ -440,6 +447,17 @@ export default function AppShowcaseDetail({
440447
userAddresses
441448
);
442449

450+
// For groupId 1 (Setup & app tour), also open links if conditionValues is a URL or path
451+
if (quest.conditionType === 'isLinkVisited' && quest.conditionValues) {
452+
if (quest.conditionValues.startsWith('http')) {
453+
// Open external link in new tab
454+
window.open(quest.conditionValues, '_blank', 'noopener,noreferrer');
455+
} else if (quest.conditionValues.startsWith('/')) {
456+
// Navigate to internal route
457+
router.push(quest.conditionValues);
458+
}
459+
}
460+
443461
if (isCompleted) {
444462
// Update quest status to completed if the action was successful
445463
updateQuestStatus(quest.id.toString(), 'completed', false);
@@ -621,7 +639,7 @@ export default function AppShowcaseDetail({
621639
style={{ width: `${overallProgress.percentage}%` }}
622640
/>
623641
{/* Milestone markers */}
624-
{[5, 10, 15, 20, 40, 60].map((milestone, index) => {
642+
{[10, 30, 50, 83].map((milestone, index) => {
625643
// Only show milestone if it's less than or equal to the total quests
626644
if (milestone <= overallProgress.total) {
627645
const isCompleted = overallProgress.completed >= milestone;

devconnect-app/src/app/wallet/WalletTab.tsx

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useNetworkSwitcher } from '@/hooks/useNetworkSwitcher';
99
import NetworkLogo from '@/components/NetworkLogo';
1010
import NetworkModal from '@/components/NetworkModal';
1111
import WalletModal from '@/components/WalletModal';
12+
import { toast } from 'sonner';
1213

1314
// Image assets from local public/images directory
1415
const imgPara = '/images/paraLogo.png';
@@ -82,6 +83,7 @@ export default function WalletTab() {
8283
const [isRefreshing, setIsRefreshing] = useState(false);
8384
const [showNetworkModal, setShowNetworkModal] = useState(false);
8485
const [showWalletModal, setShowWalletModal] = useState(false);
86+
const [addressCopied, setAddressCopied] = useState(false);
8587

8688
// Debug logging - track if component is receiving props
8789
console.log('🏠 [WALLET_TAB] Component render:', {
@@ -164,6 +166,18 @@ export default function WalletTab() {
164166
setIsRefreshing(false);
165167
};
166168

169+
// Copy address to clipboard
170+
const handleCopyAddress = async () => {
171+
if (address) {
172+
await navigator.clipboard.writeText(address);
173+
setAddressCopied(true);
174+
setTimeout(() => setAddressCopied(false), 2000);
175+
toast.success('Address copied to clipboard', {
176+
description: address,
177+
});
178+
}
179+
};
180+
167181
// Format USD value
168182
const formatUSD = (value: number) => {
169183
return new Intl.NumberFormat('en-US', {
@@ -281,37 +295,76 @@ export default function WalletTab() {
281295
</div>
282296

283297
{/* Wallet Info - centered with dropdown */}
284-
<button
285-
onClick={() => {
286-
if (!address) {
287-
router.push('/onboarding');
288-
} else {
289-
setShowWalletModal(true);
290-
}
291-
}}
292-
className="flex items-center gap-2 px-2 py-1 hover:bg-gray-100 rounded transition-colors"
293-
>
294-
{identity?.avatar ? (
298+
<div className="flex items-center gap-1">
299+
<button
300+
onClick={() => {
301+
if (!address) {
302+
router.push('/onboarding');
303+
} else {
304+
setShowWalletModal(true);
305+
}
306+
}}
307+
className="flex items-center gap-2 px-2 py-1 hover:bg-gray-100 rounded transition-colors"
308+
>
309+
{identity?.avatar ? (
310+
<img
311+
src={identity.avatar}
312+
alt="avatar"
313+
className="w-5 h-5 rounded-full"
314+
/>
315+
) : (
316+
<img src={imgPara} alt="checkbox" className="w-5 h-5" />
317+
)}
318+
<span className="text-[#242436] text-base font-normal">
319+
{address
320+
? identity?.name ||
321+
`${address.slice(0, 6)}...${address.slice(-4)}`
322+
: 'Not connected'}
323+
</span>
295324
<img
296-
src={identity.avatar}
297-
alt="avatar"
298-
className="w-5 h-5 rounded-full"
325+
src={imgKeyboardArrowDown}
326+
alt="dropdown"
327+
className="w-4 h-4"
299328
/>
300-
) : (
301-
<img src={imgPara} alt="checkbox" className="w-5 h-5" />
329+
</button>
330+
{address && (
331+
<button
332+
onClick={handleCopyAddress}
333+
className="p-1 hover:bg-gray-100 rounded transition-colors relative"
334+
title={addressCopied ? 'Copied!' : 'Copy address'}
335+
>
336+
{addressCopied ? (
337+
<svg
338+
className="w-4 h-4 text-green-600"
339+
fill="none"
340+
stroke="currentColor"
341+
viewBox="0 0 24 24"
342+
>
343+
<path
344+
strokeLinecap="round"
345+
strokeLinejoin="round"
346+
strokeWidth={2}
347+
d="M5 13l4 4L19 7"
348+
/>
349+
</svg>
350+
) : (
351+
<svg
352+
className="w-4 h-4 text-[#36364c]"
353+
fill="none"
354+
stroke="currentColor"
355+
viewBox="0 0 24 24"
356+
>
357+
<path
358+
strokeLinecap="round"
359+
strokeLinejoin="round"
360+
strokeWidth={2}
361+
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
362+
/>
363+
</svg>
364+
)}
365+
</button>
302366
)}
303-
<span className="text-[#242436] text-base font-normal">
304-
{address
305-
? identity?.name ||
306-
`${address.slice(0, 6)}...${address.slice(-4)}`
307-
: 'Not connected'}
308-
</span>
309-
<img
310-
src={imgKeyboardArrowDown}
311-
alt="dropdown"
312-
className="w-4 h-4"
313-
/>
314-
</button>
367+
</div>
315368
</div>
316369

317370
{/* Email Display */}
@@ -398,7 +451,7 @@ export default function WalletTab() {
398451
Receive
399452
</span>
400453
</div>
401-
<div className="flex-1 flex flex-col items-center gap-2">
454+
{/* <div className="flex-1 flex flex-col items-center gap-2">
402455
<button
403456
onClick={handleSwapClick}
404457
className="bg-white border border-[#f0f0f4] rounded-[4px] p-4 w-full aspect-square flex items-center justify-center hover:bg-gray-50 transition-colors cursor-pointer"
@@ -408,7 +461,7 @@ export default function WalletTab() {
408461
<span className="text-[#36364c] text-sm font-medium tracking-[-0.1px]">
409462
Swap
410463
</span>
411-
</div>
464+
</div> */}
412465
<div className="flex-1 flex flex-col items-center gap-2">
413466
<button
414467
onClick={handleScanClick}

0 commit comments

Comments
 (0)