feat(analytics): complete Rybbit tracking integration
Some checks failed
Build and Deploy / build (push) Has been cancelled
Some checks failed
Build and Deploy / build (push) Has been cancelled
- Add Rybbit server-side tracking to analytics-server.ts for order completion and revenue - Add trackNewsletterSignup to analytics.ts and wire up NewsletterSection - Add cart tracking to CartDrawer (cart view, remove from cart) - All ecommerce events now track to both OpenPanel and Rybbit
This commit is contained in:
@@ -8,6 +8,7 @@ import { X, Minus, Plus, Trash2, ShoppingBag } from "lucide-react";
|
||||
import { useTranslations, useLocale } from "next-intl";
|
||||
import { useSaleorCheckoutStore } from "@/stores/saleorCheckoutStore";
|
||||
import { formatPrice } from "@/lib/saleor";
|
||||
import { useAnalytics } from "@/lib/analytics";
|
||||
|
||||
export default function CartDrawer() {
|
||||
const t = useTranslations("Cart");
|
||||
@@ -26,11 +27,13 @@ export default function CartDrawer() {
|
||||
initCheckout,
|
||||
clearError,
|
||||
} = useSaleorCheckoutStore();
|
||||
const { trackCartView, trackRemoveFromCart } = useAnalytics();
|
||||
|
||||
const lines = getLines();
|
||||
const total = getTotal();
|
||||
const lineCount = getLineCount();
|
||||
const initializedRef = useRef(false);
|
||||
const lastCartStateRef = useRef<{ count: number; total: number } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initializedRef.current && locale) {
|
||||
@@ -52,6 +55,22 @@ export default function CartDrawer() {
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && lines.length > 0) {
|
||||
const currentState = { count: lineCount, total };
|
||||
if (!lastCartStateRef.current ||
|
||||
lastCartStateRef.current.count !== currentState.count ||
|
||||
lastCartStateRef.current.total !== currentState.total) {
|
||||
trackCartView({
|
||||
total,
|
||||
currency: checkout?.totalPrice?.gross?.currency || "RSD",
|
||||
item_count: lineCount,
|
||||
});
|
||||
lastCartStateRef.current = currentState;
|
||||
}
|
||||
}
|
||||
}, [isOpen, lineCount, total]);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
@@ -181,7 +200,14 @@ export default function CartDrawer() {
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => removeLine(line.id)}
|
||||
onClick={() => {
|
||||
trackRemoveFromCart({
|
||||
id: line.variant.product.id,
|
||||
name: line.variant.product.name,
|
||||
quantity: line.quantity,
|
||||
});
|
||||
removeLine(line.id);
|
||||
}}
|
||||
disabled={isLoading}
|
||||
className="p-2 text-[#999999] hover:text-red-500 transition-colors"
|
||||
aria-label={t("removeItem")}
|
||||
|
||||
@@ -4,14 +4,17 @@ import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { useAnalytics } from "@/lib/analytics";
|
||||
|
||||
export default function NewsletterSection() {
|
||||
const t = useTranslations("Newsletter");
|
||||
const [email, setEmail] = useState("");
|
||||
const [status, setStatus] = useState<"idle" | "success" | "error">("idle");
|
||||
const { trackNewsletterSignup } = useAnalytics();
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
trackNewsletterSignup(email, "footer");
|
||||
setStatus("success");
|
||||
setEmail("");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user