From 87a804cec60ae66cdfbd0831f4b3c015698fbd04 Mon Sep 17 00:00:00 2001 From: edehvictor Date: Wed, 4 Mar 2026 11:25:08 +0100 Subject: [PATCH 1/4] fix: replace useModal with absolute overlay for disabled claim state --- src/pages/gd/Claim/OldClaim.tsx | 61 +++++++++-------- src/pages/gd/Claim/useDisabledClaimModal.tsx | 69 ++++++++++---------- 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/pages/gd/Claim/OldClaim.tsx b/src/pages/gd/Claim/OldClaim.tsx index ff5301046..2eb520925 100644 --- a/src/pages/gd/Claim/OldClaim.tsx +++ b/src/pages/gd/Claim/OldClaim.tsx @@ -23,7 +23,7 @@ import { import { useAppKit } from '@reown/appkit/react' import { QueryParams } from '@usedapp/core' import { noop } from 'lodash' -// import { useFeatureFlagWithPayload } from 'posthog-react-native' +import { useFeatureFlagWithPayload } from 'posthog-react-native' import moment from 'moment' import { getEnv } from 'utils/env' @@ -39,8 +39,7 @@ import BillyGrin from 'assets/images/claim/billygrin.png' import BillyConfused from 'assets/images/claim/billyconfused.png' import { useIsSimpleApp } from 'state/simpleapp/simpleapp' - -// import { useDisabledClaimingModal } from './useDisabledClaimModal' +import { useDisabledClaimingModal } from './useDisabledClaimModal' import { useGoodDappFeatures } from 'hooks/useFeaturesEnabled' const OldClaim = memo(() => { @@ -57,9 +56,11 @@ const OldClaim = memo(() => { const { open } = useAppKit() const network = SupportedV2Networks[chainId] const sendData = useSendAnalyticsData() - // todo: fix UI for displaying claiming disabled modal - // const [, payload] = useFeatureFlagWithPayload('claim-feature') - // const { enabled: claimEnabled = true, disabledMessage = '' } = (payload as any) || {} + + // Uncommented per maintainer's instructions + const [, payload] = useFeatureFlagWithPayload('claim-feature') + const { enabled: claimEnabled = true, disabledMessage = '' } = (payload as any) || {} + const { activeNetworksByFeature, activeChainFeatures } = useGoodDappFeatures() const supportedChains = activeNetworksByFeature['claimEnabled'] || [] const isProd = getEnv() === 'production' @@ -69,7 +70,14 @@ const OldClaim = memo(() => { const isHoliday = holiday >= '12-24' || holiday <= '01-01' const isSimpleApp = useIsSimpleApp() - // const { Dialog, showModal } = useDisabledClaimingModal(disabledMessage) + + // Uncommented per maintainer's instructions + const { Dialog, showModal } = useDisabledClaimingModal(disabledMessage) + + // Temporary useEffect per maintainer's instructions to trigger the modal + useEffect(() => { + showModal() + }, [showModal]) const isMinipay = isMiniPay() @@ -83,14 +91,9 @@ const OldClaim = memo(() => { return supportedChains.map((chainId) => chainNames[chainId] || `Chain ID: ${chainId}`).join(', ') }, [supportedChains]) - // there are three possible scenarios - // 1. claim amount is 0, meaning user has claimed that day - // 2. status === success, meaning user has just claimed. Could happen that claimAmount has not been updated right after tx confirmation - // 3. If neither is true, there is a claim ready for user or its a new user and FV will be triggered instead useEffect(() => { const hasClaimed = async () => { if (state.status === 'Mining') { - // don't do anything until transaction is mined return } @@ -108,14 +111,12 @@ const OldClaim = memo(() => { setRefreshRate('everyBlock') } if (claimAmount) hasClaimed().catch(noop) - // eslint-disable-next-line react-hooks-addons/no-unused-deps, react-hooks/exhaustive-deps }, [claimAmount, chainId, refreshRate]) - // upon switching chain we want temporarily to poll everyBlock up untill we have the latest data useEffect(() => { setClaimed(undefined) setRefreshRate('everyBlock') - }, [/* used */ chainId]) + }, [chainId]) const handleEvents = useCallback( (event: string) => { @@ -130,8 +131,6 @@ const OldClaim = memo(() => { sendData({ event: 'claim', action: 'claim_start', network }) break case 'finish': - // finish event does not handle rejected case - // sendData({ event: 'claim', action: 'claim_success', network }) break default: sendData({ event: 'claim', action: event, network }) @@ -143,8 +142,14 @@ const OldClaim = memo(() => { const handleClaim = useCallback(async () => { setRefreshRate('everyBlock') + + // Added check to block claim and show modal if feature flag is disabled + if (!claimEnabled) { + showModal() + return false + } + if (activeChainFeatures['claimEnabled'] || !isProd || isMinipay) { - // minipay doesnt handle gasPrice correctly, so we let it decide const claim = await send(isMinipay ? { gasPrice: undefined } : {}) if (!claim) { @@ -164,17 +169,16 @@ const OldClaim = memo(() => { sendData({ event: 'claim', action: 'claim_success', network }) return true } else { - // showModal() + showModal() } return false - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [send, network, sendData, activeChainFeatures, isSimpleApp]) + }, [send, network, sendData, activeChainFeatures, isSimpleApp, claimEnabled, showModal]) const handleConnect = useCallback(async () => { if (!address) { await open({ view: 'Connect' }) - return false // Return false so button resets when modal is dismissed + return false } return true }, [address, open]) @@ -192,7 +196,7 @@ const OldClaim = memo(() => { }, lg: { flexDirection: 'row', - justifyContent: 'justify-evenly', + justifyContent: 'space-evenly', }, }) @@ -294,9 +298,7 @@ const OldClaim = memo(() => { content: [ { description: { - text: `After claiming your G$, use it to support your community, buy products and services, support causes you care about, vote in the GoodDAO, and more. - -Learn how here`, + text: `After claiming your G$, use it to support your community, buy products and services, support causes you care about, vote in the GoodDAO, and more. \n\nLearn how here`, color: 'white', }, ...(isSmallTabletView && { imgSrc: BillyHappy }), @@ -333,10 +335,13 @@ Learn how here`, return ( <> - {/* */}
- + {/* CRITICAL LAYOUT FIX: position relative so the overlay covers just this area */} + + {/* This is the overlay we built */} + + {claimed ? ( diff --git a/src/pages/gd/Claim/useDisabledClaimModal.tsx b/src/pages/gd/Claim/useDisabledClaimModal.tsx index 0ee2df8bf..dbbae117e 100644 --- a/src/pages/gd/Claim/useDisabledClaimModal.tsx +++ b/src/pages/gd/Claim/useDisabledClaimModal.tsx @@ -1,44 +1,43 @@ -import React, { useCallback } from 'react' -import { Image, Title, useModal } from '@gooddollar/good-design' -import { Box, Text, View } from 'native-base' -import { noop } from 'lodash' +import React, { useCallback, useState } from 'react' +import { Image, Title } from '@gooddollar/good-design' +import { Box, Text } from 'native-base' import Maintance from 'assets/images/claim/maintance.png' -const DialogHeader = () => ( - - - Claiming Unavailable - - -) +export const useDisabledClaimingModal = (message: string) => { + const [isVisible, setIsVisible] = useState(false) -const DialogBody = ({ message }: { message: string }) => ( - - - - {message} - - -) + const showModal = useCallback(() => setIsVisible(true), []) -export const useDisabledClaimingModal = (message: string) => { - const { Modal, showModal } = useModal() + const Dialog = useCallback(() => { + if (!isVisible) return null - const Dialog = useCallback( - () => ( - - } - body={} - onClose={noop} - closeText="x" - /> - - ), - [Modal] - ) + return ( + + + + Claiming Unavailable + + + + {message || 'Claiming is temporarily disabled.'} + + + + ) + }, [isVisible, message]) return { Dialog, showModal } } From db72d223e1aa46d5c3791cc3ce9c767cf34381b9 Mon Sep 17 00:00:00 2001 From: edehvictor Date: Wed, 4 Mar 2026 12:10:32 +0100 Subject: [PATCH 2/4] fix: gate modal display with claimEnabled flag and remove comments --- src/pages/gd/Claim/OldClaim.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pages/gd/Claim/OldClaim.tsx b/src/pages/gd/Claim/OldClaim.tsx index 2eb520925..f73df60ee 100644 --- a/src/pages/gd/Claim/OldClaim.tsx +++ b/src/pages/gd/Claim/OldClaim.tsx @@ -71,14 +71,13 @@ const OldClaim = memo(() => { const isSimpleApp = useIsSimpleApp() - // Uncommented per maintainer's instructions const { Dialog, showModal } = useDisabledClaimingModal(disabledMessage) - // Temporary useEffect per maintainer's instructions to trigger the modal useEffect(() => { - showModal() - }, [showModal]) - + if (!claimEnabled) { + showModal() + } + }, [claimEnabled, showModal]) const isMinipay = isMiniPay() const supportedChainsDisplay = useMemo(() => { From f02b0b1528dd565e763a46aa0f10ace71f1541fb Mon Sep 17 00:00:00 2001 From: edehvictor Date: Fri, 6 Mar 2026 13:58:33 +0100 Subject: [PATCH 3/4] fix: use standard img tag to ensure maintenance asset renders --- src/pages/gd/Claim/useDisabledClaimModal.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/gd/Claim/useDisabledClaimModal.tsx b/src/pages/gd/Claim/useDisabledClaimModal.tsx index dbbae117e..3d6a7220c 100644 --- a/src/pages/gd/Claim/useDisabledClaimModal.tsx +++ b/src/pages/gd/Claim/useDisabledClaimModal.tsx @@ -1,5 +1,5 @@ -import React, { useCallback, useState } from 'react' -import { Image, Title } from '@gooddollar/good-design' +import { useCallback, useState } from 'react' +import { Title } from '@gooddollar/good-design' import { Box, Text } from 'native-base' import Maintance from 'assets/images/claim/maintance.png' @@ -20,7 +20,6 @@ export const useDisabledClaimingModal = (message: string) => { left={0} right={0} zIndex={50} - bg="rgba(0, 0, 0, 0.6)" display="flex" alignItems="center" justifyContent="center" @@ -30,7 +29,11 @@ export const useDisabledClaimingModal = (message: string) => { Claiming Unavailable - + Maintenance {message || 'Claiming is temporarily disabled.'} From 0ca1ca45efefa83c1b08187901eea1a1f834a969 Mon Sep 17 00:00:00 2001 From: edehvictor Date: Tue, 10 Mar 2026 11:23:37 +0100 Subject: [PATCH 4/4] chore: restore valid developer comments and remove temporary ones --- src/pages/gd/Claim/OldClaim.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/pages/gd/Claim/OldClaim.tsx b/src/pages/gd/Claim/OldClaim.tsx index f73df60ee..2c3ee2948 100644 --- a/src/pages/gd/Claim/OldClaim.tsx +++ b/src/pages/gd/Claim/OldClaim.tsx @@ -57,7 +57,6 @@ const OldClaim = memo(() => { const network = SupportedV2Networks[chainId] const sendData = useSendAnalyticsData() - // Uncommented per maintainer's instructions const [, payload] = useFeatureFlagWithPayload('claim-feature') const { enabled: claimEnabled = true, disabledMessage = '' } = (payload as any) || {} @@ -78,6 +77,7 @@ const OldClaim = memo(() => { showModal() } }, [claimEnabled, showModal]) + const isMinipay = isMiniPay() const supportedChainsDisplay = useMemo(() => { @@ -90,9 +90,14 @@ const OldClaim = memo(() => { return supportedChains.map((chainId) => chainNames[chainId] || `Chain ID: ${chainId}`).join(', ') }, [supportedChains]) + // there are three possible scenarios + // 1. claim amount is 0, meaning user has claimed that day + // 2. status === success, meaning user has just claimed. Could happen that claimAmount has not been updated right after tx confirmation + // 3. If neither is true, there is a claim ready for user or its a new user and FV will be triggered instead useEffect(() => { const hasClaimed = async () => { if (state.status === 'Mining') { + // don't do anything until transaction is mined return } @@ -110,12 +115,14 @@ const OldClaim = memo(() => { setRefreshRate('everyBlock') } if (claimAmount) hasClaimed().catch(noop) + // eslint-disable-next-line react-hooks-addons/no-unused-deps, react-hooks/exhaustive-deps }, [claimAmount, chainId, refreshRate]) + // upon switching chain we want temporarily to poll everyBlock up untill we have the latest data useEffect(() => { setClaimed(undefined) setRefreshRate('everyBlock') - }, [chainId]) + }, [/* used */ chainId]) const handleEvents = useCallback( (event: string) => { @@ -130,6 +137,8 @@ const OldClaim = memo(() => { sendData({ event: 'claim', action: 'claim_start', network }) break case 'finish': + // finish event does not handle rejected case + // sendData({ event: 'claim', action: 'claim_success', network }) break default: sendData({ event: 'claim', action: event, network }) @@ -142,13 +151,13 @@ const OldClaim = memo(() => { const handleClaim = useCallback(async () => { setRefreshRate('everyBlock') - // Added check to block claim and show modal if feature flag is disabled if (!claimEnabled) { showModal() return false } if (activeChainFeatures['claimEnabled'] || !isProd || isMinipay) { + // minipay doesnt handle gasPrice correctly, so we let it decide const claim = await send(isMinipay ? { gasPrice: undefined } : {}) if (!claim) { @@ -172,12 +181,13 @@ const OldClaim = memo(() => { } return false + // eslint-disable-next-line react-hooks/exhaustive-deps }, [send, network, sendData, activeChainFeatures, isSimpleApp, claimEnabled, showModal]) const handleConnect = useCallback(async () => { if (!address) { await open({ view: 'Connect' }) - return false + return false // Return false so button resets when modal is dismissed } return true }, [address, open]) @@ -336,9 +346,7 @@ const OldClaim = memo(() => {
- {/* CRITICAL LAYOUT FIX: position relative so the overlay covers just this area */} - {/* This is the overlay we built */} {claimed ? (