Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add transaction status tracking #1086

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.6.3",
"@jest/globals": "^29.7.0",
"@onflow/typedefs": "^1.4.0",
"@tsconfig/docusaurus": "^2.0.3",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.14",
Expand Down
79 changes: 79 additions & 0 deletions src/components/ChallengeModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState } from 'react';
import { Button } from '../ui/design-system/src/lib/Components/Button';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBrain } from '@fortawesome/free-solid-svg-icons';
import Modal from '@site/src/ui/design-system/src/lib/Components/Modal';
import { submitNoopChallenge } from '../utils/gold-star';
import * as fcl from '@onflow/fcl';
import { useProfile } from '../hooks/use-profile';
import { useCurrentUser } from '../hooks/use-current-user';
import { getChallengeIdentifier } from '../utils/flow';
import { GOLD_STAR_CHALLENGES } from '../utils/constants';

const ChallengeModal: React.FC<{
isOpen: boolean;
onClose: () => void;
}> = ({ isOpen, onClose }) => {
const [txStatus, setTxStatus] = useState<string | null>(null);
const { user } = useCurrentUser();
const { profile, mutate: mutateProfile } = useProfile(user.addr);

const completeChallenge = async () => {
setTxStatus('Pending Approval...');
try {
const txId = await submitNoopChallenge();

setTxStatus('Submitting Challenge...');

fcl
.tx(txId)
.onceSealed()
.then(() => {
mutateProfile();
});

await fcl.tx(txId).onceExecuted();

if (profile) {
mutateProfile(
{
...profile,
submissions: {
[getChallengeIdentifier(GOLD_STAR_CHALLENGES.NOOP_CHALLENGE)]: {
completed: true,
},
},
},
false,
);
}
} catch (error) {
console.error('Failed to complete challenge', error);
} finally {
setTxStatus(null);
onClose();
}
};

return (
<Modal isOpen={isOpen} onClose={onClose} title="Challenge Details">
<div className="space-y-4 text-center">
<FontAwesomeIcon icon={faBrain} size="5x" className="text-green-500" />
<p className="text-lg text-gray-700 mt-4">
By completing this challenge, you are declaring your intent to learn
Flow and explore its capabilities.
</p>
<Button
size="lg"
className="w-full py-4 text-lg font-semibold mt-6"
onClick={completeChallenge}
disabled={txStatus !== null}
>
{txStatus ? txStatus : 'Complete Challenge'}
</Button>
</div>
</Modal>
);
};

export default ChallengeModal;
40 changes: 32 additions & 8 deletions src/components/ProfileModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import RemovableTag from '@site/src/ui/design-system/src/lib/Components/Removabl
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrophy } from '@fortawesome/free-solid-svg-icons';
import { useChallenges } from '../hooks/use-challenges';
import * as fcl from '@onflow/fcl';

interface ProfileModalProps {
isOpen: boolean;
Expand Down Expand Up @@ -44,7 +45,7 @@ const ProfileModal: React.FC<ProfileModalProps> = ({ isOpen, onClose }) => {
deployedContracts: {},
});
const [loaded, setLoaded] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const [txStatus, setTxStatus] = useState<string | null>(null);
const [tags, setTags] = useState<string[]>([]);
const [tagInput, setTagInput] = useState('');

Expand Down Expand Up @@ -85,18 +86,41 @@ const ProfileModal: React.FC<ProfileModalProps> = ({ isOpen, onClose }) => {
async function handleSave() {
if (!settings) return;

setIsSaving(true);
setTxStatus('Pending Approval...');
try {
let txId: string | null = null;
if (profile) {
await setProfile(settings);
txId = await setProfile(settings);
} else {
await createProfile(settings);
txId = await createProfile(settings);
}

setTxStatus('Saving Profile...');

fcl
.tx(txId)
.onceSealed()
.then(() => {
mutateProfile();
});

await fcl.tx(txId).onceExecuted();

if (profile) {
mutateProfile({
...profile,
handle: settings.handle || profile.handle,
socials: settings.socials || profile.socials,
referralSource: settings.referralSource || profile.referralSource,
deployedContracts:
settings.deployedContracts || profile.deployedContracts,
});
}
} catch (e) {
console.error(e);
} finally {
setIsSaving(false);
mutateProfile();
setTxStatus(null);
onClose();
}
}

Expand Down Expand Up @@ -211,9 +235,9 @@ const ProfileModal: React.FC<ProfileModalProps> = ({ isOpen, onClose }) => {
size="sm"
className="w-full max-w-md"
onClick={handleSave}
disabled={!hasChanges() || !settings || isSaving}
disabled={!hasChanges() || !settings || !!txStatus}
>
Save
{txStatus ? txStatus : 'Save Profile'}
</Button>
</div>
</div>
Expand Down
39 changes: 5 additions & 34 deletions src/components/ProgressModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import Modal from '@site/src/ui/design-system/src/lib/Components/Modal';
import Checklist from '@site/src/components/ProgressChecklist';
import { Button } from '@site/src/ui/design-system/src/lib/Components/Button';
import { useProgress } from '../hooks/use-progress';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBrain } from '@fortawesome/free-solid-svg-icons';
import { submitNoopChallenge } from '../utils/gold-star';
import ChallengeModal from './ChallengeModal';

interface ProgressModalProps {
isOpen: boolean;
Expand All @@ -30,11 +29,6 @@ const ProgressModal: React.FC<ProgressModalProps> = ({
setChallengeModalOpen(false);
};

const completeChallenge = async () => {
await submitNoopChallenge();
closeChallengeModal();
};

return (
<>
<Modal isOpen={isOpen} onClose={onClose} title="Progress">
Expand Down Expand Up @@ -69,33 +63,10 @@ const ProgressModal: React.FC<ProgressModalProps> = ({
</div>
</Modal>

{/* Challenge Modal */}
{challengeModalOpen && (
<Modal
isOpen={challengeModalOpen}
onClose={closeChallengeModal}
title="Challenge Details"
>
<div className="space-y-4 text-center">
<FontAwesomeIcon
icon={faBrain}
size="5x"
className="text-green-500"
/>
<p className="text-lg text-gray-700 mt-4">
By completing this challenge, you are declaring your intent to
learn Flow and explore its capabilities.
</p>
<Button
size="lg"
className="w-full py-4 text-lg font-semibold mt-6"
onClick={completeChallenge}
>
Complete Challenge
</Button>
</div>
</Modal>
)}
<ChallengeModal
isOpen={challengeModalOpen}
onClose={closeChallengeModal}
/>
</>
);
};
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3387,7 +3387,7 @@
isomorphic-ws "^5.0.0"
ws "^8.18.0"

"@onflow/typedefs@1.4.0":
"@onflow/typedefs@1.4.0", "@onflow/typedefs@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@onflow/typedefs/-/typedefs-1.4.0.tgz#21963c4a334cb15f7759b90f25eee177d32885f6"
integrity sha512-7b4C3F4Ztayx6XdQz/7YoHMzZ6kzy37dLxdVCV/PAsAunq9Jfu32HQaf8a0NCk0L0aM7FS2zT1Om4k7b5KP4Xg==
Expand Down