import React, { FC, PropsWithChildren, useCallback, useEffect, useState } from "react"; import { useWizard, Wizard } from "react-use-wizard"; import { View } from "native-base"; import { useEthers } from "@usedapp/core"; import { isEmpty, noop } from "lodash"; import { SupportedChains, useSendAnalytics } from "@gooddollar/web3sdk-v2"; // import { isTxReject } from "../utils/transactionType"; import { CheckAvailableOffers, CheckAvailableOffersProps } from "../../goodid"; import { useGoodId } from "../../../hooks"; import { StartClaim, PreClaim } from "../screens"; import { PostClaim } from "../screens/PostClaim"; import { ErrorModal, TxDetailsModal, TxModal } from "../../../core/web3/modals"; import { useClaimContext } from "../context/ClaimContext"; import { UbiWizardHeader } from "../../../core/layout"; import { ethers } from "ethers"; const WizardWrapper: FC> = ({ skipOffer, children }) => { const { claimDetails, claimFlowStatus, error, loading, poolsDetails, txDetails, withSignModals, onUpgrade, setTxDetails, setError, onClaimSuccess, onClaimFailed, onReset } = useClaimContext(); const { account, chainId } = useEthers(); const { goToStep, stepCount } = useWizard(); const lastStep = stepCount - 1; const { isClaiming, isClaimingDone, error: claimError, remainingClaims, claimReceipts } = claimFlowStatus; const { transaction, isOpen } = txDetails; const { certificates } = useGoodId(account ?? ""); const { track } = useSendAnalytics(); const customTitle = { title: /*i18n*/ { id: "Please sign with \n your wallet \n({remainingClaims} transaction(s) left)", values: { remainingClaims: remainingClaims } } }; const handleClose = useCallback(() => { setError(undefined); }, [claimFlowStatus]); const handleNext = useCallback(async () => { if (isClaimingDone) { await onClaimSuccess(); goToStep(lastStep); } else if (remainingClaims === 0 && claimError) { await onClaimFailed(); } }, [account, claimDetails, claimFlowStatus, claimReceipts, loading, poolsDetails]); useEffect(() => { void (async () => { void handleNext(); })(); }, [/*used*/ claimFlowStatus.isClaimingDone, claimFlowStatus.remainingClaims]); useEffect(() => { if (remainingClaims === 0 && claimReceipts?.length > 0) { claimReceipts.every((receipt: ethers.providers.TransactionReceipt | undefined) => { if (!receipt) { track("goodid_error", { error: "claimReceipts failed", message: "One or more claims failed", user: account, chainId: chainId }); } else { track("CLAIM_SUCCESS", { contract: receipt.to, user: account }); } }); } }, [remainingClaims, claimReceipts]); useEffect(() => { if (!account) { goToStep(0); } else if (chainId === SupportedChains.FUSE) { goToStep(1); } else if (account && chainId && !isEmpty(certificates)) { const hasValidCertificates = certificates.some(cert => cert.certificate); if (hasValidCertificates) { if (skipOffer) { onReset(); goToStep(2); } else { goToStep(1); } } else { onUpgrade(); } } }, [account, /*used*/ chainId, certificates, skipOffer]); return ( {error ? : null} {isClaiming && withSignModals ? ( ) : remainingClaims !== undefined ? ( 0} onClose={handleClose} /> ) : null} {isOpen ? ( setTxDetails((prev: any) => ({ ...prev, isOpen: false }))} tx={transaction} /> ) : null} {children} ); }; export const ClaimWizard: FC> = ({ account, chainId, isDev = false, withNavBar = false, onExit }) => { const { setError } = useClaimContext(); const [skipOffer, setSkipOffer] = useState(false); const { track } = useSendAnalytics(); const onDone = useCallback( async (e: Error | boolean | undefined) => { if (e instanceof Error && e.message) { track("goodid_error", { error: "checkOffers failed", message: e.message, e }); setError(e.message); } else { setSkipOffer(e); } }, [skipOffer] ); return ( } header={} > {chainId === SupportedChains.CELO ? ( ) : null} ); };