Merge pull request #212 from presenton/feat/basic-telemetry
feat/basic telemetry
This commit is contained in:
commit
dffe9f5098
15 changed files with 58 additions and 76 deletions
|
|
@ -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<GenerateButtonProps> = ({
|
|||
onSubmit
|
||||
}) => {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const isDisabled =
|
||||
loadingState.isLoading ||
|
||||
|
|
@ -36,8 +35,13 @@ const GenerateButton: React.FC<GenerateButtonProps> = ({
|
|||
<Button
|
||||
disabled={isDisabled}
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Generate_Presentation_Button_Clicked, { pathname, query });
|
||||
if (!streamState.isLoading && !streamState.isStreaming) {
|
||||
if (!selectedLayoutGroup) {
|
||||
trackEvent(MixpanelEvent.Outline_Select_Template_Button_Clicked, { pathname });
|
||||
} else {
|
||||
trackEvent(MixpanelEvent.Outline_Generate_Presentation_Button_Clicked, { pathname });
|
||||
}
|
||||
}
|
||||
onSubmit();
|
||||
}}
|
||||
className="bg-[#5146E5] w-full rounded-lg text-base sm:text-lg py-4 sm:py-6 font-instrument_sans font-semibold hover:bg-[#5146E5]/80 text-white disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { CheckCircle } from "lucide-react";
|
||||
import React from "react";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { trackEvent, MixpanelEvent } from "@/utils/mixpanel";
|
||||
import { LayoutGroup } from "../types/index";
|
||||
import { useLayout } from "../../context/LayoutContext";
|
||||
|
|
@ -21,12 +21,10 @@ const GroupLayouts: React.FC<GroupLayoutsProps> = ({
|
|||
const fonts = getCustomTemplateFonts(group.id.split("custom-")[1]);
|
||||
useFontLoader(fonts || []);
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Group_Layout_Selected_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Group_Layout_Selected_Clicked, { pathname });
|
||||
onSelectLayoutGroup(group);
|
||||
}}
|
||||
className={`relative p-4 rounded-lg border cursor-pointer transition-all duration-200 ${
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
import { OutlineItem } from "./OutlineItem";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { FileText } from "lucide-react";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { trackEvent, MixpanelEvent } from "@/utils/mixpanel";
|
||||
|
||||
interface OutlineContentProps {
|
||||
|
|
@ -42,7 +42,6 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
|
|||
);
|
||||
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
return (
|
||||
<div className="space-y-6 font-instrument_sans">
|
||||
|
|
@ -116,8 +115,7 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
|
|||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Outline_Add_Slide_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Outline_Add_Slide_Button_Clicked, { pathname });
|
||||
onAddSlide();
|
||||
}}
|
||||
disabled={isLoading || isStreaming}
|
||||
|
|
@ -136,8 +134,7 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
|
|||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Outline_Add_Slide_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Outline_Add_Slide_Button_Clicked, { pathname });
|
||||
onAddSlide();
|
||||
}}
|
||||
className="text-blue-600 border-blue-200"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { RootState } from "@/store/store";
|
|||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { trackEvent, MixpanelEvent } from "@/utils/mixpanel";
|
||||
import { AlertCircle } from "lucide-react";
|
||||
import { useGroupLayouts } from "../hooks/useGroupLayouts";
|
||||
|
|
@ -19,7 +19,6 @@ import { useFontLoader } from "../hooks/useFontLoader";
|
|||
const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
|
||||
const { renderSlideContent, loading } = useGroupLayouts();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const [contentLoading, setContentLoading] = useState(true);
|
||||
const { getCustomTemplateFonts } = useLayout()
|
||||
const dispatch = useDispatch();
|
||||
|
|
@ -87,7 +86,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
|
|||
<Button
|
||||
className="mt-4 bg-red-500 text-white hover:bg-red-600 focus:ring-4 focus:ring-red-300"
|
||||
onClick={() => {
|
||||
trackEvent(MixpanelEvent.PdfMaker_Retry_Button_Clicked, { pathname, query: searchParams?.toString() });
|
||||
trackEvent(MixpanelEvent.PdfMaker_Retry_Button_Clicked, { pathname });
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
import Wrapper from "@/components/Wrapper";
|
||||
import { useRouter, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
|
|
@ -42,7 +42,6 @@ const Header = ({
|
|||
const [showLoader, setShowLoader] = useState(false);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
|
||||
const { presentationData, isStreaming } = useSelector(
|
||||
|
|
@ -145,8 +144,7 @@ const Header = ({
|
|||
<div className={`space-y-2 max-md:mt-4 ${mobile ? "" : "bg-white"} rounded-lg`}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Header_Export_PDF_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Header_Export_PDF_Button_Clicked, { pathname });
|
||||
handleExportPdf();
|
||||
}}
|
||||
variant="ghost"
|
||||
|
|
@ -156,8 +154,7 @@ const Header = ({
|
|||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Header_Export_PPTX_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Header_Export_PPTX_Button_Clicked, { pathname });
|
||||
handleExportPptx();
|
||||
}}
|
||||
variant="ghost"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import SidePanel from "./SidePanel";
|
|||
import SlideContent from "./SlideContent";
|
||||
import Header from "./Header";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { trackEvent, MixpanelEvent } from "@/utils/mixpanel";
|
||||
import { AlertCircle, Loader2 } from "lucide-react";
|
||||
import Help from "./Help";
|
||||
|
|
@ -26,7 +26,6 @@ const PresentationPage: React.FC<PresentationPageProps> = ({
|
|||
presentation_id,
|
||||
}) => {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
// State management
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedSlide, setSelectedSlide] = useState(0);
|
||||
|
|
@ -114,7 +113,7 @@ const PresentationPage: React.FC<PresentationPageProps> = ({
|
|||
<p className="text-center mb-4">
|
||||
We couldn't load your presentation. Please try again.
|
||||
</p>
|
||||
<Button onClick={() => { const query = searchParams?.toString(); trackEvent(MixpanelEvent.PresentationPage_Refresh_Page_Button_Clicked, { pathname, query }); window.location.reload(); }}>Refresh Page</Button>
|
||||
<Button onClick={() => { trackEvent(MixpanelEvent.PresentationPage_Refresh_Page_Button_Clicked, { pathname }); window.location.reload(); }}>Refresh Page</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
<div
|
||||
onClick={() => {
|
||||
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) => {
|
|||
<ToolTip content="Delete slide">
|
||||
<div
|
||||
onClick={() => {
|
||||
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) => {
|
|||
<button
|
||||
disabled={isUpdating}
|
||||
type="submit"
|
||||
className={`bg-gradient-to-r from-[#9034EA] to-[#5146E5] rounded-[32px] px-4 py-2 text-white flex items-center justify-end gap-2 ml-auto ${
|
||||
isUpdating ? "opacity-70 cursor-not-allowed" : ""
|
||||
}`}
|
||||
className={`bg-gradient-to-r from-[#9034EA] to-[#5146E5] rounded-[32px] px-4 py-2 text-white flex items-center justify-end gap-2 ml-auto ${isUpdating ? "opacity-70 cursor-not-allowed" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Slide_Update_From_Prompt_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Slide_Update_From_Prompt_Button_Clicked, { pathname });
|
||||
}}
|
||||
>
|
||||
{isUpdating ? "Updating..." : "Update"}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
checkIfSelectedOllamaModelIsPulled,
|
||||
pullOllamaModel,
|
||||
} from "@/utils/providerUtils";
|
||||
import { useRouter, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import LLMProviderSelection from "@/components/LLMSelection";
|
||||
import Header from "../dashboard/components/Header";
|
||||
import { LLMConfig } from "@/types/llm_config";
|
||||
|
|
@ -28,7 +28,6 @@ interface ButtonState {
|
|||
const SettingsPage = () => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const userConfigState = useSelector((state: RootState) => state.userConfig);
|
||||
const [llmConfig, setLlmConfig] = useState<LLMConfig>(
|
||||
userConfigState.llm_config
|
||||
|
|
@ -64,8 +63,7 @@ const SettingsPage = () => {
|
|||
}, [downloadingModel?.downloaded, downloadingModel?.size]);
|
||||
|
||||
const handleSaveConfig = async () => {
|
||||
const query = searchParams?.toString();
|
||||
trackEvent(MixpanelEvent.Settings_SaveConfiguration_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.Settings_SaveConfiguration_Button_Clicked, { pathname });
|
||||
try {
|
||||
setButtonState(prev => ({
|
||||
...prev,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useParams, useRouter, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useParams, useRouter, usePathname } from "next/navigation";
|
||||
import LoadingStates from "../components/LoadingStates";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -21,7 +21,6 @@ const GroupLayoutPreview = () => {
|
|||
const router = useRouter();
|
||||
const slug = params.slug as string;
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const { getFullDataByGroup, loading, refetch } = useLayout();
|
||||
const layoutGroup = getFullDataByGroup(slug);
|
||||
|
|
@ -181,8 +180,7 @@ const GroupLayoutPreview = () => {
|
|||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString?.() as string | undefined;
|
||||
trackEvent(MixpanelEvent.TemplatePreview_Back_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.TemplatePreview_Back_Button_Clicked, { pathname });
|
||||
router.back();
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
|
|
@ -194,8 +192,7 @@ const GroupLayoutPreview = () => {
|
|||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const query = searchParams?.toString?.() as string | undefined;
|
||||
trackEvent(MixpanelEvent.TemplatePreview_All_Groups_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.TemplatePreview_All_Groups_Button_Clicked, { pathname });
|
||||
router.push("/template-preview");
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
|
|
@ -204,8 +201,7 @@ const GroupLayoutPreview = () => {
|
|||
All Groups
|
||||
</Button>
|
||||
{slug.includes('custom-') && <button className=" border border-red-200 flex justify-center items-center gap-2 text-red-700 px-4 py-1 rounded-md" onClick={() => {
|
||||
const query = searchParams?.toString?.() as string | undefined;
|
||||
trackEvent(MixpanelEvent.TemplatePreview_Delete_Templates_Button_Clicked, { pathname, query });
|
||||
trackEvent(MixpanelEvent.TemplatePreview_Delete_Templates_Button_Clicked, { pathname });
|
||||
trackEvent(MixpanelEvent.TemplatePreview_Delete_Templates_API_Call);
|
||||
deleteLayouts();
|
||||
}}><Trash2 className="w-4 h-4" />Delete</button>}
|
||||
|
|
@ -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]}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}</>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<LLMConfig>(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,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ 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',
|
||||
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',
|
||||
|
|
@ -24,6 +27,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',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue