From 06f0d51156d717997a4ec8a4d3495d6161f60d6c Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 11 Dec 2024 15:18:52 -0300 Subject: [PATCH 1/6] feat: add sentry error boundary wrapper --- .../app/errorBoundary/errorBoundary.tsx | 51 +++++++++++++++++++ src/components/app/errorBoundary/fallback.tsx | 40 +++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/components/app/errorBoundary/errorBoundary.tsx create mode 100644 src/components/app/errorBoundary/fallback.tsx diff --git a/src/components/app/errorBoundary/errorBoundary.tsx b/src/components/app/errorBoundary/errorBoundary.tsx new file mode 100644 index 0000000000..11e599a853 --- /dev/null +++ b/src/components/app/errorBoundary/errorBoundary.tsx @@ -0,0 +1,51 @@ +import { ReactNode } from 'react' +import * as Sentry from '@sentry/react' +import { Extras, Primitive } from '@sentry/types' + +import { ErrorFallbackComponent } from '@/components/app/errorBoundary/fallback' + +interface ErrorBoundaryProps extends Sentry.ErrorBoundaryProps { + children: ReactNode + sessionId?: string + tags?: { [key: string]: Primitive } + extras?: Extras + fallback?: Sentry.ErrorBoundaryProps['fallback'] + severityLevel?: Sentry.SeverityLevel +} + +export function ErrorBoundary({ + children, + sessionId, + tags, + extras, + fallback, + severityLevel, +}: ErrorBoundaryProps) { + return ( + { + if (sessionId) { + scope.setUser({ + id: sessionId, + idType: 'session', + }) + } + + if (tags) { + scope.setTags(tags) + } + + if (extras) { + scope.setExtras(extras) + } + + scope.setLevel(severityLevel ?? 'warning') + + return scope + }} + fallback={fallback ?? ErrorFallbackComponent} + > + {children} + + ) +} diff --git a/src/components/app/errorBoundary/fallback.tsx b/src/components/app/errorBoundary/fallback.tsx new file mode 100644 index 0000000000..1baee87fa7 --- /dev/null +++ b/src/components/app/errorBoundary/fallback.tsx @@ -0,0 +1,40 @@ +'use client' + +import { useRouter } from 'next/navigation' + +import { Button } from '@/components/ui/button' +import { NextImage } from '@/components/ui/image' +import { PageTitle } from '@/components/ui/pageTitleText' + +export function ErrorFallbackComponent() { + const router = useRouter() + + return ( +
+
+ + +
+ Something went wrong +
+
+ +
+ +
+
+ ) +} From c72d682bda14ca5e7c58cd503fd484f563c17869 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 11 Dec 2024 15:19:51 -0300 Subject: [PATCH 2/6] refactor: fix typo --- .../(homepageDialogDeeplink)/action/[action]/all/page.tsx | 4 ++-- .../app/userActionGridCTAs/hooks/useGridCTAs.ts | 6 +++--- .../app/userActionGridCTAs/hooks/useOrderedCTAs.ts | 8 ++++---- src/components/app/userActionGridCTAs/index.tsx | 8 ++++---- .../app/userActionGridCTAs/successScreenCTAS.tsx | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/[action]/all/page.tsx index fd37f08d36..e1b69b4449 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/components/app/userActionGridCTAs/hooks/useGridCTAs.ts b/src/components/app/userActionGridCTAs/hooks/useGridCTAs.ts index 6fd678509a..fc84c492a1 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 7e13bc518b..e05c3763c4 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 e64a7fbec4..75eaf5bf6a 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 cf09fe7b03..15e7a55326 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} /> ) From c8d591b68f81f53a093da7936d44f17541bdc2cf Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 11 Dec 2024 16:39:32 -0300 Subject: [PATCH 3/6] feat: add boundary into actions, thirdweb login, donate and map --- .../authentication/thirdwebLoginContent.tsx | 11 ++- .../app/pageDonate/donateButton.tsx | 14 ++- .../app/pageHome/delayedRecentActivity.tsx | 30 ++++-- .../components/userActionGridCTA.tsx | 96 +++++++++++++++---- .../web}/errorBoundary/fallback.tsx | 0 .../web/errorBoundary/index.tsx} | 9 +- 6 files changed, 125 insertions(+), 35 deletions(-) rename src/{components/app => utils/web}/errorBoundary/fallback.tsx (100%) rename src/{components/app/errorBoundary/errorBoundary.tsx => utils/web/errorBoundary/index.tsx} (82%) diff --git a/src/components/app/authentication/thirdwebLoginContent.tsx b/src/components/app/authentication/thirdwebLoginContent.tsx index f7f891a950..e854d6deff 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 fa55db9c85..c28924d42d 100644 --- a/src/components/app/pageDonate/donateButton.tsx +++ b/src/components/app/pageDonate/donateButton.tsx @@ -6,6 +6,7 @@ import { Button } from '@/components/ui/button' import { openWindow } from '@/utils/shared/openWindow' import { triggerServerActionForForm } from '@/utils/web/formUtils' import { toastGenericError } from '@/utils/web/toastUtils' +import { ErrorBoundary } from '@/utils/web/errorBoundary' export function DonateButton() { const [buttonState, setButtonState] = React.useState<'completed' | 'loading'>('completed') @@ -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 2d1cc4a637..7a126d17ec 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 f310a40e6c..8ccb2d551c 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/errorBoundary/fallback.tsx b/src/utils/web/errorBoundary/fallback.tsx similarity index 100% rename from src/components/app/errorBoundary/fallback.tsx rename to src/utils/web/errorBoundary/fallback.tsx diff --git a/src/components/app/errorBoundary/errorBoundary.tsx b/src/utils/web/errorBoundary/index.tsx similarity index 82% rename from src/components/app/errorBoundary/errorBoundary.tsx rename to src/utils/web/errorBoundary/index.tsx index 11e599a853..903bc561f0 100644 --- a/src/components/app/errorBoundary/errorBoundary.tsx +++ b/src/utils/web/errorBoundary/index.tsx @@ -1,12 +1,14 @@ +'use client' + import { ReactNode } from 'react' import * as Sentry from '@sentry/react' import { Extras, Primitive } from '@sentry/types' -import { ErrorFallbackComponent } from '@/components/app/errorBoundary/fallback' +import { getUserSessionIdOnClient } from '@/utils/web/clientUserSessionId' +import { ErrorFallbackComponent } from '@/utils/web/errorBoundary/fallback' interface ErrorBoundaryProps extends Sentry.ErrorBoundaryProps { children: ReactNode - sessionId?: string tags?: { [key: string]: Primitive } extras?: Extras fallback?: Sentry.ErrorBoundaryProps['fallback'] @@ -15,7 +17,6 @@ interface ErrorBoundaryProps extends Sentry.ErrorBoundaryProps { export function ErrorBoundary({ children, - sessionId, tags, extras, fallback, @@ -24,6 +25,8 @@ export function ErrorBoundary({ return ( { + const sessionId = getUserSessionIdOnClient() + if (sessionId) { scope.setUser({ id: sessionId, From ea86be3c7c9b04140c4eaef3e8405e855c8e2e96 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Wed, 11 Dec 2024 16:49:13 -0300 Subject: [PATCH 4/6] chore: adjust lint --- src/components/app/pageDonate/donateButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/app/pageDonate/donateButton.tsx b/src/components/app/pageDonate/donateButton.tsx index c28924d42d..cd05fd02fc 100644 --- a/src/components/app/pageDonate/donateButton.tsx +++ b/src/components/app/pageDonate/donateButton.tsx @@ -4,9 +4,9 @@ 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' -import { ErrorBoundary } from '@/utils/web/errorBoundary' export function DonateButton() { const [buttonState, setButtonState] = React.useState<'completed' | 'loading'>('completed') From 5f79d62b3afe0e67ad6278907fb5763b103c4932 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Thu, 12 Dec 2024 11:54:44 -0300 Subject: [PATCH 5/6] refactor: add error boundary to deeplink actions --- .../action/become-member/page.tsx | 39 ++++++++++++++++++- .../action/call/page.tsx | 26 ++++++++++--- .../action/email-debate/page.tsx | 24 ++++++++++-- .../action/email/page.tsx | 22 +++++++++-- .../action/live-event/[slug]/page.tsx | 26 ++++++++++--- .../action/nft-mint/page.tsx | 36 ++++++++++++----- .../action/pledge/page.tsx | 22 +++++++++-- .../action/share/page.tsx | 22 +++++++++-- .../action/sign-up/page.tsx | 1 + .../action/tweet-at-person/[slug]/page.tsx | 30 ++++++++++---- .../action/voter-registration/page.tsx | 26 ++++++++++--- .../action/voting-day/page.tsx | 26 ++++++++++--- .../action/voting-information/page.tsx | 26 ++++++++++--- 13 files changed, 270 insertions(+), 56 deletions(-) diff --git a/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx b/src/app/[locale]/(homepageDialogDeeplink)/action/become-member/page.tsx index b2568b22c7..0b6f22f676 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 914a8c2691..c40f279e22 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 4c9712e1ba..30c041613e 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 26d33aa24a..16d377edb1 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 a6765fc766..bd886d3347 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 4832a5e19b..bf6ab353ce 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 acf222bffa..1def5905aa 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 73c67e8aa5..8a4d1f3b93 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 652033977c..856fcf59a0 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 f982e19453..45ab63bf94 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 5f07edc147..be74d2b18b 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 96c7ca9623..0f52cd98ee 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 4a10663612..aeec1a1035 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 ( - -
- -
-
+ + +
+ +
+
+
) } From 1359e63db6c8a604b4cb7bae3ac63218cc3c5c30 Mon Sep 17 00:00:00 2001 From: Olavo Parno Date: Thu, 12 Dec 2024 14:56:23 -0300 Subject: [PATCH 6/6] refactor: remove fallback and adjust severity level --- src/utils/web/errorBoundary/fallback.tsx | 40 ------------------------ src/utils/web/errorBoundary/index.tsx | 15 +++------ 2 files changed, 4 insertions(+), 51 deletions(-) delete mode 100644 src/utils/web/errorBoundary/fallback.tsx diff --git a/src/utils/web/errorBoundary/fallback.tsx b/src/utils/web/errorBoundary/fallback.tsx deleted file mode 100644 index 1baee87fa7..0000000000 --- a/src/utils/web/errorBoundary/fallback.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client' - -import { useRouter } from 'next/navigation' - -import { Button } from '@/components/ui/button' -import { NextImage } from '@/components/ui/image' -import { PageTitle } from '@/components/ui/pageTitleText' - -export function ErrorFallbackComponent() { - const router = useRouter() - - return ( -
-
- - -
- Something went wrong -
-
- -
- -
-
- ) -} diff --git a/src/utils/web/errorBoundary/index.tsx b/src/utils/web/errorBoundary/index.tsx index 903bc561f0..b8b007a591 100644 --- a/src/utils/web/errorBoundary/index.tsx +++ b/src/utils/web/errorBoundary/index.tsx @@ -5,23 +5,15 @@ import * as Sentry from '@sentry/react' import { Extras, Primitive } from '@sentry/types' import { getUserSessionIdOnClient } from '@/utils/web/clientUserSessionId' -import { ErrorFallbackComponent } from '@/utils/web/errorBoundary/fallback' interface ErrorBoundaryProps extends Sentry.ErrorBoundaryProps { children: ReactNode tags?: { [key: string]: Primitive } extras?: Extras - fallback?: Sentry.ErrorBoundaryProps['fallback'] severityLevel?: Sentry.SeverityLevel } -export function ErrorBoundary({ - children, - tags, - extras, - fallback, - severityLevel, -}: ErrorBoundaryProps) { +export function ErrorBoundary({ children, tags, extras, severityLevel }: ErrorBoundaryProps) { return ( { @@ -42,11 +34,12 @@ export function ErrorBoundary({ scope.setExtras(extras) } - scope.setLevel(severityLevel ?? 'warning') + if (severityLevel) { + scope.setLevel(severityLevel) + } return scope }} - fallback={fallback ?? ErrorFallbackComponent} > {children}