From 83be1e9b750becfeb7dddd2b57273ce6b2958f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Voron?= Date: Fri, 24 Jan 2025 11:40:48 +0100 Subject: [PATCH] clients/web: tweak loading status of checkout submit button --- .../web/src/components/Checkout/Checkout.tsx | 21 ++++++++++++------- .../src/providers/CheckoutFormProvider.tsx | 4 ++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/clients/apps/web/src/components/Checkout/Checkout.tsx b/clients/apps/web/src/components/Checkout/Checkout.tsx index f13f48dcd7..abd811aa77 100644 --- a/clients/apps/web/src/components/Checkout/Checkout.tsx +++ b/clients/apps/web/src/components/Checkout/Checkout.tsx @@ -16,7 +16,7 @@ import type { CheckoutPublicConfirmed } from '@polar-sh/sdk/models/components/ch import type { Stripe, StripeElements } from '@stripe/stripe-js' import { useTheme } from 'next-themes' import { useRouter } from 'next/navigation' -import { useCallback, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' export interface CheckoutProps { embed?: boolean @@ -38,14 +38,19 @@ const Checkout = ({ embed: _embed, theme: _theme }: CheckoutProps) => { const theme = _theme || (resolvedTheme as 'light' | 'dark') const router = useRouter() + const [fullLoading, setFullLoading] = useState(false) + const loading = useMemo( + () => confirmLoading || fullLoading, + [confirmLoading, fullLoading], + ) const [listenFulfillment, fullfillmentLabel] = useCheckoutFulfillmentListener( client, checkout, ) - const [fullfillmentLoading, setFullfillmentLoading] = useState(false) - - const loading = fullfillmentLoading || confirmLoading - const label = fullfillmentLabel || loadingLabel + const label = useMemo( + () => fullfillmentLabel || loadingLabel, + [fullfillmentLabel, loadingLabel], + ) const confirm = useCallback( async ( @@ -53,10 +58,12 @@ const Checkout = ({ embed: _embed, theme: _theme }: CheckoutProps) => { stripe: Stripe | null, elements: StripeElements | null, ) => { + setFullLoading(true) let confirmedCheckout: CheckoutPublicConfirmed try { confirmedCheckout = await _confirm(data, stripe, elements) } catch (error) { + setFullLoading(false) throw error } @@ -83,9 +90,7 @@ const Checkout = ({ embed: _embed, theme: _theme }: CheckoutProps) => { // It ensures the user will have an up-to-date status when they are redirected, // especially if the external URL doesn't implement proper webhook handling if (!isInternalURL) { - setFullfillmentLoading(true) await listenFulfillment() - setFullfillmentLoading(false) } if (checkout.embedOrigin) { @@ -100,7 +105,7 @@ const Checkout = ({ embed: _embed, theme: _theme }: CheckoutProps) => { } if (isInternalURL || !embed) { - router.push(parsedURL.toString()) + await router.push(parsedURL.toString()) } return confirmedCheckout diff --git a/clients/packages/checkout/src/providers/CheckoutFormProvider.tsx b/clients/packages/checkout/src/providers/CheckoutFormProvider.tsx index 2fb829af27..df8151198c 100644 --- a/clients/packages/checkout/src/providers/CheckoutFormProvider.tsx +++ b/clients/packages/checkout/src/providers/CheckoutFormProvider.tsx @@ -200,9 +200,8 @@ export const CheckoutFormProvider = ({ confirmationTokenId: confirmationToken.id, }) } catch (e) { - throw e - } finally { setLoading(false) + throw e } setLoadingLabel('Payment successful! Getting your products ready') @@ -221,6 +220,7 @@ export const CheckoutFormProvider = ({ } } + setLoading(false) return updatedCheckout }, [checkout, setError, _confirm],