w-lab-app/src/components/domains/profile/subscriptions/CancelSubscriptionModalProvider/CancelSubscriptionModalProvider.tsx
2025-09-12 21:45:46 +02:00

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>
);
}