80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { usePathname } from "next/navigation";
|
|
|
|
import { useRetainingStore } from "@/providers/retaining-store-provider";
|
|
|
|
/**
|
|
* Hook for tracking retaining funnel progress
|
|
* Handles:
|
|
* - Step tracking when navigating between pages
|
|
* - Browser back button handling
|
|
* - Journey state management
|
|
*/
|
|
export function useRetainingTracker() {
|
|
const pathname = usePathname();
|
|
const { journey, updateCurrentStep, completeStep } = useRetainingStore(
|
|
state => state
|
|
);
|
|
|
|
const lastPathnameRef = useRef<string>("");
|
|
|
|
// Map pathname to step names
|
|
const getStepFromPathname = (path: string): string => {
|
|
if (path.includes("/appreciate-choice")) return "appreciate-choice";
|
|
if (path.includes("/what-reason")) return "what-reason";
|
|
if (path.includes("/second-chance")) return "second-chance";
|
|
if (path.includes("/change-mind")) return "change-mind";
|
|
if (path.includes("/stop-for-30-days")) return "stop-for-30-days";
|
|
if (path.includes("/cancellation-of-subscription"))
|
|
return "cancellation-of-subscription";
|
|
if (path.includes("/plan-cancelled")) return "plan-cancelled";
|
|
if (path.includes("/subscription-stopped")) return "subscription-stopped";
|
|
if (path.includes("/stay-50-done")) return "stay-50-done";
|
|
return "unknown";
|
|
};
|
|
|
|
// Track step changes and handle browser navigation
|
|
useEffect(() => {
|
|
if (!pathname.includes("/retaining") || !journey) return;
|
|
|
|
const currentStep = getStepFromPathname(pathname);
|
|
const lastPathname = lastPathnameRef.current;
|
|
|
|
// Update current step if changed
|
|
if (currentStep !== "unknown" && currentStep !== journey.currentStep) {
|
|
updateCurrentStep(currentStep);
|
|
|
|
// Complete previous step if we moved forward
|
|
if (lastPathname && !lastPathname.includes(currentStep)) {
|
|
const previousStep = getStepFromPathname(lastPathname);
|
|
if (previousStep !== "unknown") {
|
|
completeStep(previousStep);
|
|
}
|
|
}
|
|
}
|
|
|
|
lastPathnameRef.current = pathname;
|
|
}, [pathname, journey, updateCurrentStep, completeStep]);
|
|
|
|
// Get current journey summary for debugging
|
|
const getJourneySummary = () => {
|
|
if (!journey) return null;
|
|
|
|
return {
|
|
currentStep: journey.currentStep,
|
|
totalChoices: journey.choices.length,
|
|
completedSteps: journey.completedSteps,
|
|
funnel: journey.funnel,
|
|
duration: Date.now() - journey.startedAt,
|
|
};
|
|
};
|
|
|
|
return {
|
|
getJourneySummary,
|
|
isTracking: !!journey,
|
|
currentStep: journey?.currentStep,
|
|
};
|
|
}
|