diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx index fd37f08d3..e1b69b444 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx @@ -17,7 +17,7 @@ export default function UserActionCampaigns() { const { data, isLoading } = useApiResponseForUserPerformedUserActionTypes() const performedUserActionTypes = data?.performedUserActionTypes ?? [] - const { performeduserActionObj } = useGridCTAs({ + const { performedUserActionObj } = useGridCTAs({ performedUserActionTypes, }) @@ -37,7 +37,7 @@ export default function UserActionCampaigns() { diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx index b2568b22c..0b6f22f67 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx @@ -1,6 +1,9 @@ +import { UserActionType } from '@prisma/client' + import { getAuthenticatedData } from '@/components/app/pageUserProfile/getAuthenticatedData' import { RedirectToSignUpComponent } from '@/components/app/redirectToSignUp' import { PageProps } from '@/types' +import { ErrorBoundary } from '@/utils/web/errorBoundary' import { PageBecomeMember } from './pageBecomeMember' @@ -11,8 +14,40 @@ export default async function UserActionBecomeMemberDeepLink({ params }: PagePro const user = await getAuthenticatedData() if (!user) { - return + return ( + + + + ) } - return + return ( + + + + ) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/call/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/call/page.tsx index 914a8c269..c40f279e2 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/call/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/call/page.tsx @@ -1,19 +1,35 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormCallCongresspersonDeeplinkWrapper } from '@/components/app/userActionFormCallCongressperson/homepageDialogDeeplinkWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionCallCongresspersonDeepLink({ params }: PageProps) { return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/email-debate/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/email-debate/page.tsx index 4c9712e1b..30c041613 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/email-debate/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/email-debate/page.tsx @@ -1,15 +1,33 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormEmailDebateDeeplinkWrapper } from '@/components/app/userActionFormEmailDebate/homepageDialogDeeplinkWrapper' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' +import { UserActionEmailCampaignName } from '@/utils/shared/userActionCampaigns' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionEmailDebateDeepLink({ params }: PageProps) { return ( - - - + + + + + ) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/email/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/email/page.tsx index 26d33aa24..16d377edb 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/email/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/email/page.tsx @@ -1,15 +1,31 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormEmailCongresspersonDeeplinkWrapper } from '@/components/app/userActionFormEmailCongressperson/homepageDialogDeeplinkWrapper' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionEmailCongresspersonDeepLink({ params }: PageProps) { return ( - - - + + + + + ) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/live-event/[slug]/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/live-event/[slug]/page.tsx index a6765fc76..bd886d334 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/live-event/[slug]/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/live-event/[slug]/page.tsx @@ -1,3 +1,4 @@ +import { UserActionType } from '@prisma/client' import { Metadata } from 'next' import { notFound } from 'next/navigation' @@ -9,6 +10,7 @@ import { PageProps } from '@/types' import { generateMetadataDetails } from '@/utils/server/metadataUtils' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { UserActionLiveEventCampaignName } from '@/utils/shared/userActionCampaigns' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION['30_SECONDS'] export const dynamic = 'error' @@ -40,10 +42,24 @@ export default async function UserActionLiveEventDeepLink({ params }: Props) { } return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/nft-mint/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/nft-mint/page.tsx index 4832a5e19..bf6ab353c 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/nft-mint/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/nft-mint/page.tsx @@ -1,24 +1,40 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { HomepageDialogDeeplinkNFTMintWrapper } from '@/components/app/userActionFormNFTMint/homepageDialogDeeplinkNFTMintWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionNFTMintDeepLink({ params }: PageProps) { return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/pledge/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/pledge/page.tsx index acf222bff..1def5905a 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/pledge/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/pledge/page.tsx @@ -1,15 +1,31 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormVoterAttestationDeeplinkWrapper } from '@/components/app/userActionFormVoterAttestation/homepageDialogDeeplinkWrapper' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionVoterAttestationDeepLink({ params }: PageProps) { return ( - - - + + + + + ) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/share/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/share/page.tsx index 73c67e8aa..8a4d1f3b9 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/share/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/share/page.tsx @@ -1,11 +1,27 @@ +import { UserActionType } from '@prisma/client' + import { UserActionFormShareOnTwitterDeeplinkWrapper } from '@/components/app/userActionFormShareOnTwitter/homepageDialogDeeplinkWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export default function UserActionShareOnTwitterDeepLink() { return ( -
- -
+ +
+ +
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/sign-up/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/sign-up/page.tsx index 652033977..856fcf59a 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/sign-up/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/sign-up/page.tsx @@ -61,6 +61,7 @@ export default function UserActionOptInSWCDeepLink() { 'max-md:pt-16', )} > + {/* ThirdwebLoginContent already with its own ErrorBoundary with severity level Fatal */} handleRedirectOnLogin()} /> ) diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/tweet-at-person/[slug]/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/tweet-at-person/[slug]/page.tsx index f982e1945..45ab63bf9 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/tweet-at-person/[slug]/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/tweet-at-person/[slug]/page.tsx @@ -1,3 +1,4 @@ +import { UserActionType } from '@prisma/client' import { Metadata } from 'next' import { notFound } from 'next/navigation' @@ -10,6 +11,7 @@ import { generateMetadataDetails } from '@/utils/server/metadataUtils' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { UserActionTweetAtPersonCampaignName } from '@/utils/shared/userActionCampaigns' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION['30_SECONDS'] export const dynamic = 'error' @@ -47,12 +49,26 @@ export default async function UserActionTweetAtPersonDeepLink({ params }: Props) } return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/voter-registration/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/voter-registration/page.tsx index 5f07edc14..be74d2b18 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/voter-registration/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/voter-registration/page.tsx @@ -1,19 +1,35 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormVoterRegistrationDeeplinkWrapper } from '@/components/app/userActionFormVoterRegistration/homepageDialogDeeplinkWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionVoterRegistrationDeepLink({ params }: PageProps) { return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/voting-day/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/voting-day/page.tsx index 96c7ca962..0f52cd98e 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/voting-day/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/voting-day/page.tsx @@ -1,19 +1,35 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionVotingDayDeeplinkWrapper } from '@/components/app/userActionVotingDay/homepageDialogDeeplinkWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionVotingDayDeepLink({ params }: PageProps) { return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/voting-information/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/voting-information/page.tsx index 4a1066361..aeec1a103 100644 --- a/src/app/[locale]/(homepageDialogDeeplink)/action/voting-information/page.tsx +++ b/src/app/[locale]/(homepageDialogDeeplink)/action/voting-information/page.tsx @@ -1,19 +1,35 @@ +import { UserActionType } from '@prisma/client' + import { HomepageDialogDeeplinkLayout } from '@/components/app/homepageDialogDeeplinkLayout' import { UserActionFormVotingInformationDeeplinkWrapper } from '@/components/app/userActionFormVotingInformationResearched/homepageDialogDeeplinkWrapper' import { dialogContentPaddingStyles } from '@/components/ui/dialog/styles' import { PageProps } from '@/types' import { SECONDS_DURATION } from '@/utils/shared/seconds' import { cn } from '@/utils/web/cn' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export const revalidate = SECONDS_DURATION.HOUR export const dynamic = 'error' export default function UserActionVotingInformationDeepLink({ params }: PageProps) { return ( - -
- -
-
+ + +
+ +
+
+
) } diff --git a/src/components/app/authentication/thirdwebLoginContent.tsx b/src/components/app/authentication/thirdwebLoginContent.tsx index f7f891a95..e854d6def 100644 --- a/src/components/app/authentication/thirdwebLoginContent.tsx +++ b/src/components/app/authentication/thirdwebLoginContent.tsx @@ -1,4 +1,5 @@ 'use client' + import { useCallback, useEffect, useRef } from 'react' import { useRouter } from 'next/navigation' import { AuthOption } from 'node_modules/thirdweb/dist/types/wallets/types' @@ -25,6 +26,7 @@ import { isCypress } from '@/utils/shared/executionEnvironment' import { thirdwebClient } from '@/utils/shared/thirdwebClient' import { apiUrls } from '@/utils/shared/urls' import { trackSectionVisible } from '@/utils/web/clientAnalytics' +import { ErrorBoundary } from '@/utils/web/errorBoundary' import { theme } from '@/utils/web/thirdweb/theme' export interface ThirdwebLoginContentProps extends Omit { @@ -91,7 +93,12 @@ export function ThirdwebLoginContent({ }, [initialEmailAddress]) return ( - <> +
@@ -139,7 +146,7 @@ export function ThirdwebLoginContent({

- + ) } diff --git a/src/components/app/pageDonate/donateButton.tsx b/src/components/app/pageDonate/donateButton.tsx index fa55db9c8..cd05fd02f 100644 --- a/src/components/app/pageDonate/donateButton.tsx +++ b/src/components/app/pageDonate/donateButton.tsx @@ -4,6 +4,7 @@ import React from 'react' import { actionCreateCoinbaseCommerceCharge } from '@/actions/actionCreateCoinbaseCommerceCharge' import { Button } from '@/components/ui/button' import { openWindow } from '@/utils/shared/openWindow' +import { ErrorBoundary } from '@/utils/web/errorBoundary' import { triggerServerActionForForm } from '@/utils/web/formUtils' import { toastGenericError } from '@/utils/web/toastUtils' @@ -36,9 +37,16 @@ export function DonateButton() { } return (
- + + +
) } diff --git a/src/components/app/pageHome/delayedRecentActivity.tsx b/src/components/app/pageHome/delayedRecentActivity.tsx index 2d1cc4a63..7a126d17e 100644 --- a/src/components/app/pageHome/delayedRecentActivity.tsx +++ b/src/components/app/pageHome/delayedRecentActivity.tsx @@ -1,4 +1,5 @@ 'use client' + import { useRef } from 'react' import { TabsContent } from '@radix-ui/react-tabs' import { useInView } from 'framer-motion' @@ -14,6 +15,7 @@ import { useApiRecentActivity } from '@/hooks/useApiRecentActivity' import { useIntlUrls } from '@/hooks/useIntlUrls' import { useIsMobile } from '@/hooks/useIsMobile' import { SupportedLocale } from '@/intl/locales' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export function DelayedRecentActivityWithMap(props: { actions: PublicRecentActivity @@ -41,12 +43,26 @@ export function DelayedRecentActivityWithMap(props: {
) : ( - + + + ) } diff --git a/src/components/app/userActionGridCTAs/components/userActionGridCTA.tsx b/src/components/app/userActionGridCTAs/components/userActionGridCTA.tsx index f310a40e6..8ccb2d551 100644 --- a/src/components/app/userActionGridCTAs/components/userActionGridCTA.tsx +++ b/src/components/app/userActionGridCTAs/components/userActionGridCTA.tsx @@ -1,42 +1,98 @@ +import { Fragment } from 'react' + import { UserActionCard } from '@/components/app/userActionGridCTAs/components/userActionCard' import { UserActionGridCampaignsDialog } from '@/components/app/userActionGridCTAs/components/userActionGridCampaignsDialog' import type { UserActionCardProps as UserActionGridCTAProps } from '@/components/app/userActionGridCTAs/types' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export function UserActionGridCTA(props: UserActionGridCTAProps) { + const firstCampaign = props.campaigns[0] + + // If there is only one campaign, clicking the CTA will trigger the WrapperComponent for that campaign. + const shouldUseFirstCampaignWrapperComponent = props.campaignsLength === 1 + if (props.link) { // If the link property is present, the CTA will function as a link, even if there are multiple campaigns. const LinkComponent = props.link + return ( - - - + + + + + ) } - // If there is only one campaign, clicking the CTA will trigger the WrapperComponent for that campaign. - const shouldUseFirstCampaignWrapperComponent = props.campaignsLength === 1 - if (shouldUseFirstCampaignWrapperComponent) { - const WrapperComponent = props.campaigns[0].WrapperComponent - - if (!WrapperComponent) { - return - } + const WrapperComponent = firstCampaign.WrapperComponent ?? Fragment return ( - - - + + + + + ) } return ( - - - + + + + ) } diff --git a/src/components/app/userActionGridCTAs/hooks/useGridCTAs.ts b/src/components/app/userActionGridCTAs/hooks/useGridCTAs.ts index 6fd678509..fc84c492a 100644 --- a/src/components/app/userActionGridCTAs/hooks/useGridCTAs.ts +++ b/src/components/app/userActionGridCTAs/hooks/useGridCTAs.ts @@ -21,7 +21,7 @@ export function useGridCTAs({ const locale = useLocale() const isProfilePage = pathname?.includes(getIntlUrls(locale).profile()) - const performeduserActionObj = performedUserActionTypes.length + const performedUserActionObj = performedUserActionTypes.length ? performedUserActionTypes.reduce( (acc, performedUserAction) => { acc[`${performedUserAction.actionType}-${performedUserAction.campaignName}`] = @@ -47,12 +47,12 @@ export function useGridCTAs({ * If we are on the profile page, we want to show all the CTAs, including * those with campaigns inactive if the user has already performed them. */ - return campaign.isCampaignActive || (isProfilePage && !!performeduserActionObj[key]) + return campaign.isCampaignActive || (isProfilePage && !!performedUserActionObj[key]) }) return { ...cta, campaigns: filteredCampaigns } }) .filter(cta => cta.campaigns.length > 0) - return { ctas: filteredInactiveCampaigns, performeduserActionObj } + return { ctas: filteredInactiveCampaigns, performedUserActionObj } } diff --git a/src/components/app/userActionGridCTAs/hooks/useOrderedCTAs.ts b/src/components/app/userActionGridCTAs/hooks/useOrderedCTAs.ts index 7e13bc518..e05c3763c 100644 --- a/src/components/app/userActionGridCTAs/hooks/useOrderedCTAs.ts +++ b/src/components/app/userActionGridCTAs/hooks/useOrderedCTAs.ts @@ -27,7 +27,7 @@ export function useOrderedCTAs({ performedUserActionTypes, excludeUserActionTypes, }: UseOrderedCTAsProps) { - const performeduserActionObj = useMemo(() => { + const performedUserActionObj = useMemo(() => { return performedUserActionTypes.length ? performedUserActionTypes.reduce( (acc, performedUserAction) => { @@ -64,7 +64,7 @@ export function useOrderedCTAs({ const completedActions = cta.campaigns .map(campaign => { const key = `${campaign.actionType}-${campaign.campaignName}` - if (!performeduserActionObj[key]) return + if (!performedUserActionObj[key]) return return key }) @@ -76,7 +76,7 @@ export function useOrderedCTAs({ }) return uniqBy([...incompleteCTAs, ...completeCTAs], cta => `${cta.title}-${cta.description}`) - }, [filteredInactiveCampaigns, performeduserActionObj]) + }, [filteredInactiveCampaigns, performedUserActionObj]) - return { orderedCTAs, performeduserActionObj } + return { orderedCTAs, performedUserActionObj } } diff --git a/src/components/app/userActionGridCTAs/index.tsx b/src/components/app/userActionGridCTAs/index.tsx index e64a7fbec..75eaf5bf6 100644 --- a/src/components/app/userActionGridCTAs/index.tsx +++ b/src/components/app/userActionGridCTAs/index.tsx @@ -19,7 +19,7 @@ export function UserActionGridCTAs({ const { data } = useApiResponseForUserPerformedUserActionTypes() const performedUserActionTypes = data?.performedUserActionTypes ?? [] - const { ctas, performeduserActionObj } = useGridCTAs({ + const { ctas, performedUserActionObj } = useGridCTAs({ excludeUserActionTypes, performedUserActionTypes, }) @@ -29,11 +29,11 @@ export function UserActionGridCTAs({ {ctas.map(cta => { const completedCampaigns = cta.campaigns.reduce((acc, campaign) => { const key = `${campaign.actionType}-${campaign.campaignName}` - return performeduserActionObj[key] ? acc + 1 : acc + return performedUserActionObj[key] ? acc + 1 : acc }, 0) const filteredCampaigns = cta.campaigns.filter(campaign => { const key = `${campaign.actionType}-${campaign.campaignName}` - return campaign.isCampaignActive || !!performeduserActionObj[key] + return campaign.isCampaignActive || !!performedUserActionObj[key] }) return ( @@ -51,7 +51,7 @@ export function UserActionGridCTAs({ key={cta.title + cta.description} link={cta.link} mobileCTADescription={cta.mobileCTADescription} - performedUserActions={performeduserActionObj} + performedUserActions={performedUserActionObj} title={cta.title} /> ) diff --git a/src/components/app/userActionGridCTAs/successScreenCTAS.tsx b/src/components/app/userActionGridCTAs/successScreenCTAS.tsx index cf09fe7b0..15e7a5532 100644 --- a/src/components/app/userActionGridCTAs/successScreenCTAS.tsx +++ b/src/components/app/userActionGridCTAs/successScreenCTAS.tsx @@ -17,7 +17,7 @@ export function SuccessScreenCTAS({ excludeUserActionTypes, performedUserActionTypes, }: SuccessScreenCTASProps) { - const { orderedCTAs, performeduserActionObj } = useOrderedCTAs({ + const { orderedCTAs, performedUserActionObj } = useOrderedCTAs({ performedUserActionTypes, excludeUserActionTypes, }) @@ -27,11 +27,11 @@ export function SuccessScreenCTAS({ {orderedCTAs.map(cta => { const completedCampaigns = cta.campaigns.reduce((acc, campaign) => { const key = `${campaign.actionType}-${campaign.campaignName}` - return performeduserActionObj[key] ? acc + 1 : acc + return performedUserActionObj[key] ? acc + 1 : acc }, 0) const filteredCampaigns = cta.campaigns.filter(campaign => { const key = `${campaign.actionType}-${campaign.campaignName}` - return campaign.isCampaignActive || !!performeduserActionObj[key] + return campaign.isCampaignActive || !!performedUserActionObj[key] }) return ( @@ -49,7 +49,7 @@ export function SuccessScreenCTAS({ key={cta.title + cta.description} link={cta.link} mobileCTADescription={cta.mobileCTADescription} - performedUserActions={performeduserActionObj} + performedUserActions={performedUserActionObj} title={cta.title} /> ) diff --git a/src/utils/web/errorBoundary/index.tsx b/src/utils/web/errorBoundary/index.tsx new file mode 100644 index 000000000..b8b007a59 --- /dev/null +++ b/src/utils/web/errorBoundary/index.tsx @@ -0,0 +1,47 @@ +'use client' + +import { ReactNode } from 'react' +import * as Sentry from '@sentry/react' +import { Extras, Primitive } from '@sentry/types' + +import { getUserSessionIdOnClient } from '@/utils/web/clientUserSessionId' + +interface ErrorBoundaryProps extends Sentry.ErrorBoundaryProps { + children: ReactNode + tags?: { [key: string]: Primitive } + extras?: Extras + severityLevel?: Sentry.SeverityLevel +} + +export function ErrorBoundary({ children, tags, extras, severityLevel }: ErrorBoundaryProps) { + return ( + { + const sessionId = getUserSessionIdOnClient() + + if (sessionId) { + scope.setUser({ + id: sessionId, + idType: 'session', + }) + } + + if (tags) { + scope.setTags(tags) + } + + if (extras) { + scope.setExtras(extras) + } + + if (severityLevel) { + scope.setLevel(severityLevel) + } + + return scope + }} + > + {children} + + ) +}