diff --git a/apps/studio/components/interfaces/Billing/Payment/AddNewPaymentMethodModal.tsx b/apps/studio/components/interfaces/Billing/Payment/AddNewPaymentMethodModal.tsx index f822b55b0b5..0041cbb6207 100644 --- a/apps/studio/components/interfaces/Billing/Payment/AddNewPaymentMethodModal.tsx +++ b/apps/studio/components/interfaces/Billing/Payment/AddNewPaymentMethodModal.tsx @@ -8,6 +8,7 @@ import { Modal } from 'ui' import { useOrganizationPaymentMethodSetupIntent } from 'data/organizations/organization-payment-method-setup-intent-mutation' import { useSelectedOrganization, useStore } from 'hooks' import { STRIPE_PUBLIC_KEY } from 'lib/constants' +import { useIsHCaptchaLoaded } from 'stores/hcaptcha-loaded-store' import AddPaymentMethodForm from './AddPaymentMethodForm' interface AddNewPaymentMethodModalProps { @@ -30,7 +31,7 @@ const AddNewPaymentMethodModal = ({ const [intent, setIntent] = useState() const selectedOrganization = useSelectedOrganization() - const [captchaLoaded, setHCaptchaLoaded] = useState(false) + const captchaLoaded = useIsHCaptchaLoaded() const [captchaToken, setCaptchaToken] = useState(null) const [captchaRef, setCaptchaRef] = useState(null) @@ -125,7 +126,6 @@ const AddNewPaymentMethodModal = ({ onExpire={() => { setCaptchaToken(null) }} - onLoad={() => setHCaptchaLoaded(true)} /> + {!isTestEnv && } diff --git a/apps/studio/pages/new/index.tsx b/apps/studio/pages/new/index.tsx index 9a82234d40e..95fbc992686 100644 --- a/apps/studio/pages/new/index.tsx +++ b/apps/studio/pages/new/index.tsx @@ -9,6 +9,7 @@ import { NewOrgForm } from 'components/interfaces/Organization' import { WizardLayout } from 'components/layouts' import { useSetupIntent } from 'data/stripe/setup-intent-mutation' import { STRIPE_PUBLIC_KEY } from 'lib/constants' +import { useIsHCaptchaLoaded } from 'stores/hcaptcha-loaded-store' import type { NextPageWithLayout } from 'types' const stripePromise = loadStripe(STRIPE_PUBLIC_KEY) @@ -20,7 +21,7 @@ const Wizard: NextPageWithLayout = () => { const { resolvedTheme } = useTheme() const [intent, setIntent] = useState() - const [captchaLoaded, setHCaptchaLoaded] = useState(false) + const captchaLoaded = useIsHCaptchaLoaded() const [captchaToken, setCaptchaToken] = useState(null) const [captchaRef, setCaptchaRef] = useState(null) @@ -85,19 +86,13 @@ const Wizard: NextPageWithLayout = () => { ref={captchaRefCallback} sitekey={process.env.NEXT_PUBLIC_HCAPTCHA_SITE_KEY!} size="invisible" - onOpen={() => { - // [Joshen] This is to ensure that hCaptcha popup remains clickable - if (document !== undefined) document.body.classList.add('!pointer-events-auto') - }} - onClose={() => { - onLocalCancel() - if (document !== undefined) document.body.classList.remove('!pointer-events-auto') - }} onVerify={(token) => { setCaptchaToken(token) - if (document !== undefined) document.body.classList.remove('!pointer-events-auto') }} - onLoad={() => setHCaptchaLoaded(true)} + onClose={onLocalCancel} + onExpire={() => { + setCaptchaToken(null) + }} /> {intent && ( diff --git a/apps/studio/stores/hcaptcha-loaded-store.tsx b/apps/studio/stores/hcaptcha-loaded-store.tsx new file mode 100644 index 00000000000..008053d20b0 --- /dev/null +++ b/apps/studio/stores/hcaptcha-loaded-store.tsx @@ -0,0 +1,31 @@ +import HCaptcha from '@hcaptcha/react-hcaptcha' +import { proxy, useSnapshot } from 'valtio' + +const hCaptchaLoadedStoreState = proxy({ + loaded: false, + setLoaded() { + hCaptchaLoadedStoreState.loaded = true + }, +}) + +export const useIsHCaptchaLoaded = () => { + const snap = useSnapshot(hCaptchaLoadedStoreState) + + return snap.loaded +} + +const HCaptchaLoadedStore = () => { + const onLoad = () => { + hCaptchaLoadedStoreState.setLoaded() + } + + return ( + + ) +} + +export default HCaptchaLoadedStore