diff --git a/packages/app-store/alby/components/AlbyPaymentComponent.tsx b/packages/app-store/alby/components/AlbyPaymentComponent.tsx index bd8a414554..0d99643f3a 100644 --- a/packages/app-store/alby/components/AlbyPaymentComponent.tsx +++ b/packages/app-store/alby/components/AlbyPaymentComponent.tsx @@ -1,10 +1,16 @@ import Link from "next/link"; -import { useState } from "react"; +import { useSearchParams } from "next/navigation"; +import { useEffect, useState } from "react"; import QRCode from "react-qr-code"; import z from "zod"; +import type { PaymentPageProps } from "@calcom/features/ee/payments/pages/payment"; +import { useBookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect"; import { useCopy } from "@calcom/lib/hooks/useCopy"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { trpc } from "@calcom/trpc/react"; import { Button } from "@calcom/ui"; +import { showToast } from "@calcom/ui"; import { ClipboardCheck, Clipboard } from "@calcom/ui/components/icon"; import { Spinner } from "@calcom/ui/components/icon/Spinner"; @@ -13,6 +19,7 @@ interface IAlbyPaymentComponentProps { // Will be parsed on render data: unknown; }; + paymentPageProps: PaymentPageProps; } // Create zod schema for data @@ -21,8 +28,7 @@ const PaymentAlbyDataSchema = z.object({ .object({ paymentRequest: z.string(), }) - .optional(), - capture: z.object({}).optional(), + .required(), }); export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => { @@ -45,6 +51,7 @@ export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => { return (
+ {isPaying && } {!isPaying && ( <> @@ -58,6 +65,9 @@ export const AlbyPaymentComponent = (props: IAlbyPaymentComponentProps) => {
); }; + +type PaymentCheckerProps = PaymentPageProps; + +function PaymentChecker(props: PaymentCheckerProps) { + // This effect checks if the booking status has changed to "ACCEPTED" + // then reload the page to show the new payment status + // FIXME: subscribe to the exact payment instead of polling bookings + // FIXME: booking success is copied from packages/features/ee/payments/components/Payment.tsx + const searchParams = useSearchParams(); + const bookingSuccessRedirect = useBookingSuccessRedirect(); + const utils = trpc.useContext(); + const { t } = useLocale(); + useEffect(() => { + const interval = setInterval(() => { + (async () => { + if (props.booking.status === "ACCEPTED") { + return; + } + const bookingsResult = await utils.viewer.bookings.get.fetch({ + filters: { + status: "upcoming", + eventTypeIds: [props.eventType.id], + }, + }); + // TODO: is there a better way than reloading the whole page? + // currently props.booking comes from SSR + if ( + bookingsResult.bookings.some( + (booking) => booking.id === props.booking.id && booking.status === "ACCEPTED" + ) + ) { + showToast("Payment successful", "success"); + + const params: { + [k: string]: any; + } = { + uid: props.booking.uid, + email: searchParams.get("email"), + location: t("web_conferencing_details_to_follow"), + }; + + bookingSuccessRedirect({ + successRedirectUrl: props.eventType.successRedirectUrl, + query: params, + booking: props.booking, + }); + } + })(); + }, 1000); + return () => clearInterval(interval); + }, [ + bookingSuccessRedirect, + props.booking, + props.booking.id, + props.booking.status, + props.eventType.id, + props.eventType.successRedirectUrl, + props.payment.success, + searchParams, + t, + utils.viewer.bookings, + ]); + return null; +} diff --git a/packages/features/ee/payments/components/PaymentPage.tsx b/packages/features/ee/payments/components/PaymentPage.tsx index f329e1900a..478b2dd9a0 100644 --- a/packages/features/ee/payments/components/PaymentPage.tsx +++ b/packages/features/ee/payments/components/PaymentPage.tsx @@ -152,7 +152,7 @@ const PaymentPage: FC = (props) => { )} {props.payment.appId === "alby" && !props.payment.success && ( - + )} {props.payment.refunded && (
{t("refunded")}