From 66ecab957b41deb56a0a14952f535e207240b27e Mon Sep 17 00:00:00 2001 From: MarconLP <13001502+MarconLP@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:24:10 +0200 Subject: [PATCH] improve stripe user experience --- src/components/Paywall.tsx | 6 +- src/pages/videos.tsx | 137 +++++++++++++++++++++---------- src/server/api/routers/stripe.ts | 8 +- 3 files changed, 103 insertions(+), 48 deletions(-) diff --git a/src/components/Paywall.tsx b/src/components/Paywall.tsx index 18a6498..7c43c0f 100644 --- a/src/components/Paywall.tsx +++ b/src/components/Paywall.tsx @@ -26,9 +26,13 @@ export default function Paywall() { } const handleCheckout = async () => { - const { checkoutUrl } = await createCheckoutSession({ billedAnnually }); + const { checkoutUrl } = await createCheckoutSession({ + billedAnnually, + recordModalOpen, + }); if (checkoutUrl) { if (recordModalOpen) { + setOpen(false); window.open(checkoutUrl, "_blank", "noreferrer,width=500,height=500"); } else { void router.push(checkoutUrl); diff --git a/src/pages/videos.tsx b/src/pages/videos.tsx index fd04c62..ef14bef 100644 --- a/src/pages/videos.tsx +++ b/src/pages/videos.tsx @@ -17,6 +17,8 @@ import Paywall from "~/components/Paywall"; import paywallAtom from "~/atoms/paywallAtom"; import { usePostHog } from "posthog-js/react"; import Image from "next/image"; +import { useSearchParams } from "next/navigation"; +import { useEffect } from "react"; const VideoList: NextPage = () => { const [, setRecordOpen] = useAtom(recordVideoModalOpen); @@ -26,11 +28,15 @@ const VideoList: NextPage = () => { const { status, data: session } = useSession(); const { data: videos, isLoading } = api.video.getAll.useQuery(); const posthog = usePostHog(); + const searchParams = useSearchParams(); if (status === "unauthenticated") { void router.replace("/sign-in"); } + const checkoutCanceledQueryParam = searchParams.get("checkoutCanceled"); + const closeQueryParam = searchParams.get("close"); + const openRecordModal = () => { if ( !navigator?.mediaDevices?.getDisplayMedia && @@ -64,6 +70,20 @@ const VideoList: NextPage = () => { } }; + const closeWindow = + (typeof window !== "undefined" && + window.innerWidth === 500 && + window.innerHeight === 499) || + closeQueryParam === "true"; + + useEffect(() => { + if (checkoutCanceledQueryParam === "false" && closeQueryParam === "false") { + setTimeout(() => { + void router.push("/videos").then(() => router.reload()); + }, 5000); + } + }, [checkoutCanceledQueryParam, closeQueryParam]); + return ( <> @@ -107,54 +127,81 @@ const VideoList: NextPage = () => {
- {videos && videos?.length <= 0 ? ( -
-
+ {closeWindow || checkoutCanceledQueryParam === "false" ? ( + <> + {checkoutCanceledQueryParam === "false" ? ( +
+ + Successfully upgraded + + {closeQueryParam === "true" ? ( + + You can now close this window + + ) : ( + + You will be redirected shortly + + )} +
+ ) : ( - No videos found - - - Videos you record will show up here. Already got videos? - Upload them! + You can now close this window -
- - -
-
-
+ )} + ) : ( -
- {videos && - videos.map(({ title, id, createdAt, thumbnailUrl }) => ( - - ))} - - {isLoading ? ( - <> - - - - - - ) : null} -
+ <> + {videos && videos?.length <= 0 ? ( +
+
+ + No videos found + + + Videos you record will show up here. Already got videos? + Upload them! + +
+ + +
+
+
+ ) : ( +
+ {videos && + videos.map(({ title, id, createdAt, thumbnailUrl }) => ( + + ))} + + {isLoading ? ( + <> + + + + + + ) : null} +
+ )} + )}
diff --git a/src/server/api/routers/stripe.ts b/src/server/api/routers/stripe.ts index 2fce39e..b362833 100644 --- a/src/server/api/routers/stripe.ts +++ b/src/server/api/routers/stripe.ts @@ -5,7 +5,9 @@ import { z } from "zod"; export const stripeRouter = createTRPCRouter({ createCheckoutSession: protectedProcedure - .input(z.object({ billedAnnually: z.boolean() })) + .input( + z.object({ billedAnnually: z.boolean(), recordModalOpen: z.boolean() }) + ) .mutation( async ({ ctx: { prisma, stripe, session, req, posthog }, input }) => { if ( @@ -45,7 +47,9 @@ export const stripeRouter = createTRPCRouter({ quantity: 1, }, ], - success_url: `${baseUrl}/videos?checkoutSuccess=true`, + success_url: input.recordModalOpen + ? `${baseUrl}/videos?checkoutCanceled=false&close=true` + : `${baseUrl}/videos?checkoutCanceled=false&close=false`, cancel_url: `${baseUrl}/videos?checkoutCanceled=true`, subscription_data: { metadata: {