From 69eaf288b1bda5c9ae96492245f98b1a5701efda Mon Sep 17 00:00:00 2001 From: HrithikSampson Date: Thu, 12 Sep 2024 17:44:18 +0530 Subject: [PATCH] fix: multiple donation modal shown together --- .../modals/DonationByProjectOwner.tsx | 26 +++++++--- src/components/views/donate/DonateIndex.tsx | 48 +++++++++++++++--- src/components/views/donate/DonationCard.tsx | 6 +-- .../donate/OnTime/OneTimeDonationCard.tsx | 50 ++++++++----------- src/context/donate.context.tsx | 30 +++++++++++ 5 files changed, 112 insertions(+), 48 deletions(-) diff --git a/src/components/modals/DonationByProjectOwner.tsx b/src/components/modals/DonationByProjectOwner.tsx index 62978d202b..ace4ed5397 100644 --- a/src/components/modals/DonationByProjectOwner.tsx +++ b/src/components/modals/DonationByProjectOwner.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { brandColors, Button, @@ -12,27 +12,37 @@ import { useRouter } from 'next/router'; import { Modal } from '@/components/modals/Modal'; import Routes from '@/lib/constants/Routes'; import { mediaQueries } from '@/lib/constants/constants'; -import { useModalAnimation } from '@/hooks/useModalAnimation'; // Define the props interface interface DonationByProjectOwnerProps { - setShowDonationByProjectOwner: ( - showDonationByProjectOwner: boolean, - ) => void; + closeModal: () => void; } export const DonationByProjectOwner: React.FC = ({ - setShowDonationByProjectOwner, + closeModal, }) => { const { formatMessage } = useIntl(); const router = useRouter(); - const { closeModal } = useModalAnimation(setShowDonationByProjectOwner); + const [isRedirecting, setIsRedirecting] = useState(false); const navigateToAllProjects = () => { + setIsRedirecting(true); router.push(Routes.AllProjects); - closeModal(); }; + useEffect(() => { + const handleRouteChangeComplete = () => { + closeModal(); + setIsRedirecting(false); + }; + if (isRedirecting) { + router.events.on('routeChangeComplete', handleRouteChangeComplete); + } + return () => { + router.events.off('routeChangeComplete', handleRouteChangeComplete); + }; + }, [isRedirecting]); + return ( { const { formatMessage } = useIntl(); @@ -56,11 +60,13 @@ const DonateIndex: FC = () => { qrDonationStatus, draftDonationData, hasActiveQFRound, + currentDonateModal, setSuccessDonation, setQRDonationStatus, setDraftDonationData, setPendingDonationExists, startTimer, + setDonateModalByPriority, } = useDonateData(); const { renewExpirationDate, retrieveDraftDonation } = useQRCodeDonation(project); @@ -78,6 +84,7 @@ const DonateIndex: FC = () => { const [showQRCode, setShowQRCode] = React.useState( !!router.query.draft_donation, ); + const { walletAddress: address } = useGeneralWallet(); const [stopTimer, setStopTimer] = React.useState void)>(); useEffect(() => { @@ -87,10 +94,32 @@ const DonateIndex: FC = () => { }; }, [dispatch]); + const validateSanctions = async () => { + if (project.organization?.label === 'endaoment' && address) { + // We just need to check if the wallet is sanctioned for endaoment projects + const sanctioned = await isWalletSanctioned(address); + if (sanctioned) { + setDonateModalByPriority( + DonateModalPriorityValues.OFACSanctionListModal, + ); + return; + } + } + }; + useEffect(() => { - setShowDonationByProjectOwner( - userData?.id !== undefined && userData?.id === project.adminUser.id, - ); + validateSanctions(); + }, [project, address]); + + useEffect(() => { + if ( + userData?.id !== undefined && + userData?.id === project.adminUser.id + ) { + setDonateModalByPriority( + DonateModalPriorityValues.DonationByProjectOwner, + ); + } }, [userData?.id, project.adminUser]); useEffect(() => { @@ -221,11 +250,14 @@ const DonateIndex: FC = () => { <> - {showDonationByProjectOwner && ( + {currentDonateModal === + DonateModalPriorityValues.DonationByProjectOwner && ( { + setDonateModalByPriority( + DonateModalPriorityValues.None, + ); + }} /> )} {alreadyDonated && ( diff --git a/src/components/views/donate/DonationCard.tsx b/src/components/views/donate/DonationCard.tsx index 7495dc964f..e69ebaab77 100644 --- a/src/components/views/donate/DonationCard.tsx +++ b/src/components/views/donate/DonationCard.tsx @@ -53,7 +53,7 @@ export const DonationCard: FC = ({ address.chainType === ChainType.EVM && address.networkId === config.OPTIMISM_NETWORK_NUMBER, ); - + const isEndaomentProject = project?.organization?.label === 'endaoment'; const isOwnerOnEVM = project?.adminUser?.walletAddress && isAddress(project.adminUser?.walletAddress); @@ -94,10 +94,10 @@ export const DonationCard: FC = ({ // If both conditions are met, set the active tab to 'RECURRING' using the setTab function. // This ensures that the 'RECURRING' tab is active by default if project has Op Address. useEffect(() => { - if (!router.query.tab && hasOpAddress) { + if (!router.query.tab && hasOpAddress && !isEndaomentProject) { setTab(ETabs.RECURRING); } - }, [router.query, hasOpAddress]); + }, [router.query, hasOpAddress, isEndaomentProject]); return ( diff --git a/src/components/views/donate/OnTime/OneTimeDonationCard.tsx b/src/components/views/donate/OnTime/OneTimeDonationCard.tsx index 53335f2251..eb8ac4692a 100644 --- a/src/components/views/donate/OnTime/OneTimeDonationCard.tsx +++ b/src/components/views/donate/OnTime/OneTimeDonationCard.tsx @@ -35,7 +35,10 @@ import { useAppDispatch, useAppSelector } from '@/features/hooks'; import DonateToGiveth from '@/components/views/donate/DonateToGiveth'; import SaveGasFees from './SaveGasFees'; import SwitchToAcceptedChain from '@/components/views/donate/SwitchToAcceptedChain'; -import { useDonateData } from '@/context/donate.context'; +import { + DonateModalPriorityValues, + useDonateData, +} from '@/context/donate.context'; import { useModalCallback } from '@/hooks/useModalCallback'; import DonateQFEligibleNetworks from './DonateQFEligibleNetworks'; import { getActiveRound } from '@/helpers/qf'; @@ -58,8 +61,6 @@ import { TokenIcon } from '../TokenIcon/TokenIcon'; import { SelectTokenModal } from './SelectTokenModal/SelectTokenModal'; import { Spinner } from '@/components/Spinner'; import { useSolanaBalance } from '@/hooks/useSolanaBalance'; -import { isWalletSanctioned } from '@/services/donation'; -import SanctionModal from '@/components/modals/SanctionedModal'; const CryptoDonation: FC<{ setIsQRDonation: (isQRDonation: boolean) => void; @@ -76,7 +77,13 @@ const CryptoDonation: FC<{ const router = useRouter(); const { isSignedIn } = useAppSelector(state => state.user); - const { project, hasActiveQFRound, selectedOneTimeToken } = useDonateData(); + const { + project, + hasActiveQFRound, + selectedOneTimeToken, + currentDonateModal, + setDonateModalByPriority, + } = useDonateData(); const dispatch = useAppDispatch(); const { @@ -97,7 +104,6 @@ const CryptoDonation: FC<{ const [showDonateModal, setShowDonateModal] = useState(false); const [showInsufficientModal, setShowInsufficientModal] = useState(false); const [showChangeNetworkModal, setShowChangeNetworkModal] = useState(false); - const [isSanctioned, setIsSanctioned] = useState(false); const [acceptedChains, setAcceptedChains] = useState( [], ); @@ -149,10 +155,6 @@ const CryptoDonation: FC<{ address => address.chainType === ChainType.STELLAR, ); - useEffect(() => { - validateSanctions(); - }, [project, address]); - useEffect(() => { if ( (networkId || @@ -327,17 +329,6 @@ const CryptoDonation: FC<{ } }, [selectedTokenBalance, amount, selectedOneTimeToken?.address, gasfee]); - const validateSanctions = async () => { - if (project?.organization?.label === 'endaoment' && address) { - // We just need to check if the wallet is sanctioned for endaoment projects - const sanctioned = await isWalletSanctioned(address); - if (sanctioned) { - setIsSanctioned(true); - return; - } - } - }; - const amountErrorText = useMemo(() => { const totalAmount = Number(formatUnits(gasfee, tokenDecimals)).toFixed( 10, @@ -352,6 +343,14 @@ const CryptoDonation: FC<{ ); }, [gasfee, tokenDecimals, selectedOneTimeToken?.symbol, formatMessage]); + useEffect(() => { + if (showChangeNetworkModal && acceptedChains) { + setDonateModalByPriority( + DonateModalPriorityValues.ShowNetworkModal, + ); + } + }, [showChangeNetworkModal, acceptedChains]); + // We need givethDonationAmount here because we need to calculate the donation share // for Giveth. If user want to donate minimal amount to projecct, the donation share for Giveth // has to be 0, disabled in UI and DonationModal @@ -363,21 +362,14 @@ const CryptoDonation: FC<{ return ( - {isSanctioned && ( - { - setIsSanctioned(false); - setShowChangeNetworkModal(false); - }} - /> - )} {showQFModal && ( )} - {!isSanctioned && showChangeNetworkModal && acceptedChains && ( + {currentDonateModal === + DonateModalPriorityValues.ShowNetworkModal && ( >; + currentDonateModal: DonateModalPriorityValues; + setDonateModalByPriority: ( + changeCurrentModal: DonateModalPriorityValues, + ) => void; setSelectedRecurringToken: Dispatch< SetStateAction >; @@ -64,13 +68,24 @@ interface IProviderProps { project: IProject; } +export enum DonateModalPriorityValues { + None, + ShowNetworkModal, + DonationByProjectOwner, + OFACSanctionListModal, +} + const DonateContext = createContext({ setSuccessDonation: () => {}, setSelectedOneTimeToken: () => {}, setSelectedRecurringToken: () => {}, project: {} as IProject, + currentDonateModal: DonateModalPriorityValues.None, tokenStreams: {}, fetchProject: async () => {}, + setDonateModalByPriority: ( + changeCurrentModal: DonateModalPriorityValues, + ) => {}, draftDonationData: {} as IDraftDonation, fetchDraftDonation: async () => {}, qrDonationStatus: 'waiting', @@ -105,6 +120,8 @@ export const DonateProvider: FC = ({ children, project }) => { const [successDonation, setSuccessDonation] = useState(); const [projectData, setProjectData] = useState(project); + const [currentDonateModal, setCurrentDonateModal] = + useState(DonateModalPriorityValues.None); const { chain } = useAccount(); @@ -113,6 +130,17 @@ export const DonateProvider: FC = ({ children, project }) => { setSelectedRecurringToken(undefined); }, [chain]); + const setDonateModalByPriority = useCallback( + (changeModal: DonateModalPriorityValues) => { + if (changeModal === DonateModalPriorityValues.None) { + setCurrentDonateModal(DonateModalPriorityValues.None); + } else if (changeModal > currentDonateModal) { + setCurrentDonateModal(changeModal); + } + }, + [currentDonateModal], + ); + const fetchProject = useCallback(async () => { const { data } = (await client.query({ query: FETCH_PROJECT_BY_SLUG_DONATION, @@ -149,6 +177,8 @@ export const DonateProvider: FC = ({ children, project }) => { selectedOneTimeToken, pendingDonationExists, selectedRecurringToken, + setDonateModalByPriority, + currentDonateModal, setSelectedOneTimeToken, setSelectedRecurringToken, tokenStreams,