Files
cozsweet-frontend-nextjs/src/app/subscription/use-subscription-payment-flow.ts
T

97 lines
2.7 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { usePaymentRouteFlow } from "@/app/_hooks/use-payment-route-flow";
import type { PayChannel } from "@/data/schemas/payment";
import {
DEFAULT_CHARACTER,
getCharacterBySlug,
} from "@/data/constants/character";
import {
consumeSubscriptionExitUrl,
resolveSubscriptionSuccessExitUrl,
type SubscriptionReturnTo,
} from "@/lib/navigation/subscription_exit";
import type { SubscriptionType } from "./subscription-screen.helpers";
export interface UseSubscriptionPaymentFlowInput {
subscriptionType: SubscriptionType;
shouldResumePendingOrder: boolean;
returnTo: SubscriptionReturnTo;
initialPayChannel: PayChannel;
sourceCharacterSlug?: string | null;
initialPlanId?: string | null;
commercialOfferId?: string | null;
resumeOrderId?: string | null;
chatActionId?: string | null;
}
export function useSubscriptionPaymentFlow({
subscriptionType,
shouldResumePendingOrder,
returnTo,
initialPayChannel,
sourceCharacterSlug = null,
initialPlanId = null,
commercialOfferId = null,
resumeOrderId = null,
chatActionId = null,
}: UseSubscriptionPaymentFlowInput) {
const router = useRouter();
const supportCharacter = getCharacterBySlug(sourceCharacterSlug);
const exitCharacterSlug = supportCharacter?.slug ?? DEFAULT_CHARACTER.slug;
const { payment, paymentDispatch } = usePaymentRouteFlow({
initialPayChannel,
paymentType: subscriptionType,
shouldResumePendingOrder,
characterId: supportCharacter?.id,
initialPlanId,
commercialOfferId,
resumeOrderId,
chatActionId,
});
const successDialogShownOrderRef = useRef<string | null>(null);
const [showPaymentSuccessDialog, setShowPaymentSuccessDialog] =
useState(false);
useEffect(() => {
if (!payment.isPaid || !payment.currentOrderId) return;
if (successDialogShownOrderRef.current === payment.currentOrderId) return;
successDialogShownOrderRef.current = payment.currentOrderId;
setShowPaymentSuccessDialog(true);
}, [payment.currentOrderId, payment.isPaid]);
const handleBackClick = () => {
void (async () => {
router.replace(
await consumeSubscriptionExitUrl(returnTo, exitCharacterSlug),
);
})();
};
const handlePaymentSuccessClose = () => {
setShowPaymentSuccessDialog(false);
paymentDispatch({ type: "PaymentReset" });
void (async () => {
router.replace(
await resolveSubscriptionSuccessExitUrl(
returnTo,
exitCharacterSlug,
),
);
})();
};
return {
payment,
paymentDispatch,
showPaymentSuccessDialog,
handleBackClick,
handlePaymentSuccessClose,
};
}