From 88bbff499807bb9cb9bf420d0d315455d0289e24 Mon Sep 17 00:00:00 2001 From: sauravniraula Date: Wed, 13 Aug 2025 13:21:43 +0545 Subject: [PATCH 1/2] fix(nextjs): changes some event names and removes search query from button click event --- .../outline/components/GenerateButton.tsx | 12 +++++++---- .../outline/components/GroupLayouts.tsx | 6 ++---- .../outline/components/OutlineContent.tsx | 9 +++------ .../pdf-maker/PdfMakerPage.tsx | 5 ++--- .../presentation/components/Header.tsx | 9 +++------ .../components/PresentationPage.tsx | 5 ++--- .../presentation/components/SlideContent.tsx | 20 ++++++++----------- .../settings/SettingPage.tsx | 6 ++---- .../template-preview/[slug]/page.tsx | 15 +++++--------- .../upload/components/UploadPage.tsx | 3 +-- servers/nextjs/app/MixpanelInitializer.tsx | 14 ++++--------- servers/nextjs/components/Home.tsx | 9 +++------ servers/nextjs/utils/mixpanel.ts | 4 +++- 13 files changed, 46 insertions(+), 71 deletions(-) diff --git a/servers/nextjs/app/(presentation-generator)/outline/components/GenerateButton.tsx b/servers/nextjs/app/(presentation-generator)/outline/components/GenerateButton.tsx index 63b375d3..fd6a8ae2 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/components/GenerateButton.tsx +++ b/servers/nextjs/app/(presentation-generator)/outline/components/GenerateButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { usePathname, useSearchParams } from "next/navigation"; +import { usePathname } from "next/navigation"; import { trackEvent, MixpanelEvent } from "@/utils/mixpanel"; import { Button } from "@/components/ui/button"; import { LoadingState, LayoutGroup } from "../types/index"; @@ -18,7 +18,6 @@ const GenerateButton: React.FC = ({ onSubmit }) => { const pathname = usePathname(); - const searchParams = useSearchParams(); const isDisabled = loadingState.isLoading || @@ -36,8 +35,13 @@ const GenerateButton: React.FC = ({ + ); diff --git a/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx b/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx index e94f7ef2..342e7be1 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx +++ b/servers/nextjs/app/(presentation-generator)/presentation/components/SlideContent.tsx @@ -17,7 +17,7 @@ import { updateSlide, } from "@/store/slices/presentationGeneration"; import { useGroupLayouts } from "../../hooks/useGroupLayouts"; -import { usePathname, useSearchParams } from "next/navigation"; +import { usePathname } from "next/navigation"; import { trackEvent, MixpanelEvent } from "@/utils/mixpanel"; import NewSlide from "../../components/NewSlide"; @@ -38,7 +38,6 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => { // Use the centralized group layouts hook const { renderSlideContent, loading } = useGroupLayouts(); const pathname = usePathname(); - const searchParams = useSearchParams(); const handleSubmit = async () => { const element = document.getElementById( @@ -73,6 +72,7 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => { }; const onDeleteSlide = async () => { try { + trackEvent(MixpanelEvent.Slide_Delete_API_Call); dispatch(deletePresentationSlide(slide.index)); } catch (error: any) { console.error("Error deleting slide:", error); @@ -113,7 +113,7 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => { return; } if (slide.layout.includes("custom")) { - + const existingScript = document.querySelector( 'script[src*="tailwindcss.com"]' ); @@ -155,8 +155,7 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => { {!isStreaming && !loading && (
{ - const query = searchParams?.toString(); - trackEvent(MixpanelEvent.Slide_Add_New_Slide_Button_Clicked, { pathname, query }); + trackEvent(MixpanelEvent.Slide_Add_New_Slide_Button_Clicked, { pathname }); setShowNewSlideSelection(true); }} className=" bg-white shadow-md w-[80px] py-2 border hover:border-[#5141e5] duration-300 flex items-center justify-center rounded-lg cursor-pointer mx-auto" @@ -179,8 +178,7 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => {
{ - const query = searchParams?.toString(); - trackEvent(MixpanelEvent.Slide_Delete_Slide_Button_Clicked, { pathname, query }); + trackEvent(MixpanelEvent.Slide_Delete_Slide_Button_Clicked, { pathname }); onDeleteSlide(); }} className="absolute top-2 z-20 sm:top-4 right-2 sm:right-4 hidden md:block transition-transform" @@ -232,12 +230,10 @@ const SlideContent = ({ slide, index, presentationId }: SlideContentProps) => { {slug.includes('custom-') && } @@ -265,8 +261,7 @@ const GroupLayoutPreview = () => { size="sm" className="flex items-center gap-2 bg-blue-50 border border-blue-400 text-blue-700" onClick={() => { - const query = searchParams?.toString?.() as string | undefined; - trackEvent(MixpanelEvent.TemplatePreview_Open_Editor_Button_Clicked, { pathname, query }); + trackEvent(MixpanelEvent.TemplatePreview_Open_Editor_Button_Clicked, { pathname }); openEditor(fileName); }} disabled={!layoutsMap[fileName]} diff --git a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx index f9689180..e47f29cb 100644 --- a/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx +++ b/servers/nextjs/app/(presentation-generator)/upload/components/UploadPage.tsx @@ -11,7 +11,7 @@ "use client"; import React, { useState } from "react"; -import { useRouter, usePathname, useSearchParams } from "next/navigation"; +import { useRouter, usePathname } from "next/navigation"; import { useDispatch } from "react-redux"; import { clearOutlines, setPresentationId } from "@/store/slices/presentationGeneration"; import { ConfigurationSelects } from "./ConfigurationSelects"; @@ -39,7 +39,6 @@ interface LoadingState { const UploadPage = () => { const router = useRouter(); const pathname = usePathname(); - const searchParams = useSearchParams(); const dispatch = useDispatch(); // State management diff --git a/servers/nextjs/app/MixpanelInitializer.tsx b/servers/nextjs/app/MixpanelInitializer.tsx index 65b23fd6..caccf109 100644 --- a/servers/nextjs/app/MixpanelInitializer.tsx +++ b/servers/nextjs/app/MixpanelInitializer.tsx @@ -1,26 +1,20 @@ 'use client'; import { useEffect } from 'react'; -import { usePathname, useSearchParams } from 'next/navigation'; -import { initMixpanel, trackEvent, MixpanelEvent } from '@/utils/mixpanel'; +import { initMixpanel, MixpanelEvent, trackEvent } from '@/utils/mixpanel'; +import { usePathname } from 'next/navigation'; export function MixpanelInitializer({ children }: { children: React.ReactNode }) { const pathname = usePathname(); - const searchParams = useSearchParams(); // Initialize once useEffect(() => { initMixpanel(); }, []); - // Track page views on route changes useEffect(() => { - if (!pathname) return; - const query = searchParams?.toString(); - const url = query ? `${pathname}?${query}` : pathname; - trackEvent(MixpanelEvent.PageView, { url }); - }, [pathname, searchParams]); - + trackEvent(MixpanelEvent.PageView, { url: pathname }); + }, [pathname]); return <>{children}; } diff --git a/servers/nextjs/components/Home.tsx b/servers/nextjs/components/Home.tsx index 414e78cc..27f34409 100644 --- a/servers/nextjs/components/Home.tsx +++ b/servers/nextjs/components/Home.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useMemo } from "react"; import { useRouter } from "next/navigation"; import { toast } from "sonner"; -import { Loader2, Download, CheckCircle, X } from "lucide-react"; +import { Loader2, Download, CheckCircle } from "lucide-react"; import { useSelector } from "react-redux"; import { RootState } from "@/store/store"; import { handleSaveLLMConfig } from "@/utils/storeHelpers"; @@ -13,7 +13,7 @@ import { } from "@/utils/providerUtils"; import { LLMConfig } from "@/types/llm_config"; import { trackEvent, MixpanelEvent } from "@/utils/mixpanel"; -import { usePathname, useSearchParams } from "next/navigation"; +import { usePathname } from "next/navigation"; // Button state interface interface ButtonState { @@ -28,7 +28,6 @@ interface ButtonState { export default function Home() { const router = useRouter(); const pathname = usePathname(); - const searchParams = useSearchParams(); const config = useSelector((state: RootState) => state.userConfig); const [llmConfig, setLlmConfig] = useState(config.llm_config); @@ -56,9 +55,7 @@ export default function Home() { }, [downloadingModel?.downloaded, downloadingModel?.size]); const handleSaveConfig = async () => { - // Track button click with pathname and searchParams - const query = searchParams?.toString(); - trackEvent(MixpanelEvent.Home_SaveConfiguration_Button_Clicked, { pathname, query }); + trackEvent(MixpanelEvent.Home_SaveConfiguration_Button_Clicked, { pathname }); try { setButtonState(prev => ({ ...prev, diff --git a/servers/nextjs/utils/mixpanel.ts b/servers/nextjs/utils/mixpanel.ts index 0261861f..da03f2ec 100644 --- a/servers/nextjs/utils/mixpanel.ts +++ b/servers/nextjs/utils/mixpanel.ts @@ -11,7 +11,8 @@ export enum MixpanelEvent { Home_SaveConfiguration_API_Call = 'Home Save Configuration API Call', Home_CheckOllamaModelPulled_API_Call = 'Home Check Ollama Model Pulled API Call', Home_DownloadOllamaModel_API_Call = 'Home Download Ollama Model API Call', - Generate_Presentation_Button_Clicked = 'Generate Presentation Button Clicked', + Outline_Generate_Presentation_Button_Clicked = 'Outline Generate Presentation Button Clicked', + Outline_Select_Template_Button_Clicked = 'Outline Select Template Button Clicked', Outline_Add_Slide_Button_Clicked = 'Outline Add Slide Button Clicked', Group_Layout_Selected_Clicked = 'Group Layout Selected Clicked', Header_Export_PDF_Button_Clicked = 'Header Export PDF Button Clicked', @@ -24,6 +25,7 @@ export enum MixpanelEvent { Slide_Delete_Slide_Button_Clicked = 'Slide Delete Slide Button Clicked', Slide_Update_From_Prompt_Button_Clicked = 'Slide Update From Prompt Button Clicked', Slide_Edit_API_Call = 'Slide Edit API Call', + Slide_Delete_API_Call = 'Slide Delete API Call', TemplatePreview_Back_Button_Clicked = 'Template Preview Back Button Clicked', TemplatePreview_All_Groups_Button_Clicked = 'Template Preview All Groups Button Clicked', TemplatePreview_Delete_Templates_Button_Clicked = 'Template Preview Delete Templates Button Clicked', From 5f7927598520314bc40411e32390ee09b8bebfa0 Mon Sep 17 00:00:00 2001 From: sauravniraula Date: Wed, 13 Aug 2025 13:31:33 +0545 Subject: [PATCH 2/2] chore: adds ppt prepare and stream api call events --- .../outline/hooks/usePresentationGeneration.ts | 10 ++++++---- .../presentation/hooks/usePresentationStreaming.ts | 5 ++++- servers/nextjs/utils/mixpanel.ts | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/servers/nextjs/app/(presentation-generator)/outline/hooks/usePresentationGeneration.ts b/servers/nextjs/app/(presentation-generator)/outline/hooks/usePresentationGeneration.ts index 3b80204b..6743dcd1 100644 --- a/servers/nextjs/app/(presentation-generator)/outline/hooks/usePresentationGeneration.ts +++ b/servers/nextjs/app/(presentation-generator)/outline/hooks/usePresentationGeneration.ts @@ -5,6 +5,7 @@ import { toast } from "sonner"; import { clearPresentationData } from "@/store/slices/presentationGeneration"; import { PresentationGenerationApi } from "../../services/api/presentation-generation"; import { LayoutGroup, LoadingState, TABS } from "../types/index"; +import { MixpanelEvent, trackEvent } from "@/utils/mixpanel"; const DEFAULT_LOADING_STATE: LoadingState = { message: "", @@ -37,7 +38,7 @@ export const usePresentationGeneration = ( }); return false; } - if(!selectedLayoutGroup.slides.length){ + if (!selectedLayoutGroup.slides.length) { toast.error("No Slide Schema found", { description: "Please select a Group before generating presentation", }); @@ -63,7 +64,7 @@ export const usePresentationGeneration = ( } if (!validateInputs()) return; - + setLoadingState({ message: "Generating presentation data...", @@ -74,8 +75,9 @@ export const usePresentationGeneration = ( try { const layoutData = prepareLayoutData(); - + if (!layoutData) return; + trackEvent(MixpanelEvent.Presentation_Prepare_API_Call); const response = await PresentationGenerationApi.presentationPrepare({ presentation_id: presentationId, outlines: outlines, @@ -84,7 +86,7 @@ export const usePresentationGeneration = ( if (response) { dispatch(clearPresentationData()); - router.replace(`/presentation?id=${presentationId}&stream=true`); + router.replace(`/presentation?id=${presentationId}&stream=true`); } } catch (error: any) { console.error('Error In Presentation Generation(prepare).', error); diff --git a/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts b/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts index b28fe3ca..23d3c80f 100644 --- a/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts +++ b/servers/nextjs/app/(presentation-generator)/presentation/hooks/usePresentationStreaming.ts @@ -7,6 +7,7 @@ import { } from "@/store/slices/presentationGeneration"; import { jsonrepair } from "jsonrepair"; import { toast } from "sonner"; +import { MixpanelEvent, trackEvent } from "@/utils/mixpanel"; export const usePresentationStreaming = ( presentationId: string, @@ -26,6 +27,8 @@ export const usePresentationStreaming = ( dispatch(setStreaming(true)); dispatch(clearPresentationData()); + trackEvent(MixpanelEvent.Presentation_Stream_API_Call); + eventSource = new EventSource( `/api/v1/ppt/presentation/stream?presentation_id=${presentationId}` ); @@ -99,7 +102,7 @@ export const usePresentationStreaming = ( setLoading(false); dispatch(setStreaming(false)); setError(true); - break; + break; } }); diff --git a/servers/nextjs/utils/mixpanel.ts b/servers/nextjs/utils/mixpanel.ts index da03f2ec..3f51de71 100644 --- a/servers/nextjs/utils/mixpanel.ts +++ b/servers/nextjs/utils/mixpanel.ts @@ -14,6 +14,8 @@ export enum MixpanelEvent { Outline_Generate_Presentation_Button_Clicked = 'Outline Generate Presentation Button Clicked', Outline_Select_Template_Button_Clicked = 'Outline Select Template Button Clicked', Outline_Add_Slide_Button_Clicked = 'Outline Add Slide Button Clicked', + Presentation_Prepare_API_Call = 'Presentation Prepare API Call', + Presentation_Stream_API_Call = 'Presentation Stream API Call', Group_Layout_Selected_Clicked = 'Group Layout Selected Clicked', Header_Export_PDF_Button_Clicked = 'Header Export PDF Button Clicked', Header_Export_PPTX_Button_Clicked = 'Header Export PPTX Button Clicked',