Files
manoon-headless/src/components/home/ExitIntentDetector.tsx
Unchained ccf7972627 Revert programmatic SEO changes from wrong branch
These changes belong in their own feature/programmatic-seo branch
2026-04-05 05:28:55 +02:00

103 lines
3.2 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import { useScrollDepth } from "@/hooks/useScrollDepth";
import { useExitIntent } from "@/hooks/useExitIntent";
import { useVisitorStore } from "@/hooks/useVisitorStore";
import EmailCapturePopup from "./EmailCapturePopup";
import { useAnalytics } from "@/lib/analytics";
const SCROLL_POPUP_DELAY_MS = 5000;
export default function ExitIntentDetector() {
const params = useParams();
const locale = (params.locale as string) || "en";
const { trackPopupView } = useAnalytics();
const scrollTriggered = useScrollDepth(10);
const exitTriggered = useExitIntent();
const { canShowPopup, markPopupShown, markSubscribed } = useVisitorStore();
const [showPopup, setShowPopup] = useState(false);
const [trigger, setTrigger] = useState<"scroll" | "exit">("scroll");
const [country, setCountry] = useState("Unknown");
const [countryCode, setCountryCode] = useState("XX");
const [city, setCity] = useState("");
const [region, setRegion] = useState("");
const [isReady, setIsReady] = useState(false);
useEffect(() => {
const fetchCountry = async () => {
try {
const response = await fetch("/api/geoip");
if (response.ok) {
const data = await response.json();
setCountry(data.country);
setCountryCode(data.countryCode);
setCity(data.city || "");
setRegion(data.region || "");
}
} catch (error) {
console.error("Failed to get country:", error);
}
setIsReady(true);
};
fetchCountry();
}, []);
useEffect(() => {
console.log("[ExitIntent] Scroll triggered:", scrollTriggered);
console.log("[ExitIntent] Exit triggered:", exitTriggered);
console.log("[ExitIntent] isReady:", isReady);
console.log("[ExitIntent] canShowPopup:", canShowPopup());
if (!isReady || !canShowPopup()) return;
let timer: NodeJS.Timeout;
if (scrollTriggered || exitTriggered) {
const newTrigger = exitTriggered ? "exit" : "scroll";
console.log("[ExitIntent] Trigger activated:", newTrigger);
setTrigger(newTrigger);
// Exit intent shows immediately, scroll has a delay
const delay = exitTriggered ? 0 : SCROLL_POPUP_DELAY_MS;
timer = setTimeout(() => {
console.log("[ExitIntent] Timer fired, checking canShowPopup again");
if (canShowPopup()) {
console.log("[ExitIntent] Showing popup!");
setShowPopup(true);
markPopupShown(newTrigger);
trackPopupView({ trigger: newTrigger, locale, country: countryCode });
}
}, delay);
}
return () => clearTimeout(timer);
}, [scrollTriggered, exitTriggered, isReady, canShowPopup, markPopupShown, trackPopupView, locale, countryCode]);
const handleClose = () => {
setShowPopup(false);
};
const handleSubscribe = () => {
markSubscribed();
};
if (!isReady) return null;
return (
<EmailCapturePopup
isOpen={showPopup}
onClose={handleClose}
onSubscribe={handleSubscribe}
trigger={trigger}
locale={locale}
country={country}
countryCode={countryCode}
/>
);
}