110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
createContext,
|
|
ReactNode,
|
|
useCallback,
|
|
useContext,
|
|
useState,
|
|
} from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { useTranslations } from "next-intl";
|
|
|
|
import { Button, Typography } from "@/components/ui";
|
|
import Modal from "@/components/ui/Modal/Modal";
|
|
import { UserSubscription } from "@/entities/subscriptions/types";
|
|
import { useRetainingStore } from "@/providers/retaining-store-provider";
|
|
import { ROUTES } from "@/shared/constants/client-routes";
|
|
import { ERetainingFunnel } from "@/stores/retaining-store";
|
|
|
|
import styles from "./CancelSubscriptionModalProvider.module.scss";
|
|
|
|
type Ctx = { open: (sub: UserSubscription) => void };
|
|
|
|
const Context = createContext<Ctx | null>(null);
|
|
|
|
export const useCancelSubscriptionModal = () => {
|
|
const ctx = useContext(Context);
|
|
if (!ctx)
|
|
throw new Error("useCancelSubscriptionModal must be inside provider");
|
|
return ctx;
|
|
};
|
|
|
|
export default function CancelSubscriptionModalProvider({
|
|
children,
|
|
}: {
|
|
children: ReactNode;
|
|
}) {
|
|
const t = useTranslations("Subscriptions");
|
|
const router = useRouter();
|
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
const {
|
|
setCancellingSubscription,
|
|
cancellingSubscription,
|
|
setRetainingData,
|
|
startJourney,
|
|
} = useRetainingStore(state => state);
|
|
|
|
const close = useCallback(() => setIsOpen(false), []);
|
|
const open = useCallback(
|
|
(subscription: UserSubscription) => {
|
|
setCancellingSubscription(subscription);
|
|
setIsOpen(true);
|
|
},
|
|
[setCancellingSubscription]
|
|
);
|
|
|
|
const handleCancel = useCallback(async () => {
|
|
if (!cancellingSubscription) return;
|
|
|
|
// Set up retention funnel data with default Red funnel
|
|
setRetainingData({
|
|
funnel: ERetainingFunnel.Red,
|
|
cancellingSubscription,
|
|
});
|
|
|
|
// Start journey tracking
|
|
startJourney(cancellingSubscription.id);
|
|
|
|
// Close modal and redirect to retention funnel
|
|
close();
|
|
router.push(ROUTES.retainingFunnelCancelSubscription());
|
|
}, [cancellingSubscription, setRetainingData, startJourney, close, router]);
|
|
|
|
const handleStay = useCallback(() => {
|
|
close();
|
|
}, [close]);
|
|
|
|
return (
|
|
<Context.Provider value={{ open }}>
|
|
{children}
|
|
|
|
<Modal
|
|
open={!!isOpen}
|
|
onClose={close}
|
|
isCloseButtonVisible={false}
|
|
className={styles.overlay}
|
|
modalClassName={styles.modal}
|
|
>
|
|
<Typography as="h4" className={styles.title}>
|
|
{t("modal.title")}
|
|
</Typography>
|
|
<Typography as="p" className={styles.description}>
|
|
{t("modal.description")}
|
|
</Typography>
|
|
|
|
<div className={styles.actions}>
|
|
<Button className={styles.action} onClick={handleCancel}>
|
|
{t("modal.cancel_button")}
|
|
</Button>
|
|
<Button onClick={handleStay} className={styles.action}>
|
|
{t("modal.stay_button")}
|
|
</Button>
|
|
</div>
|
|
</Modal>
|
|
</Context.Provider>
|
|
);
|
|
}
|