Posthog behoben
This commit is contained in:
parent
8c5e2fa58e
commit
18f92c4285
|
|
@ -132,6 +132,48 @@ export default function DashboardPage() {
|
|||
},
|
||||
];
|
||||
|
||||
// Track Google OAuth login/signup
|
||||
useEffect(() => {
|
||||
const authMethod = searchParams.get('authMethod');
|
||||
const isNewUser = searchParams.get('isNewUser') === 'true';
|
||||
|
||||
if (authMethod === 'google') {
|
||||
const trackGoogleAuth = async () => {
|
||||
try {
|
||||
// Fetch user data from API (cookie-based auth)
|
||||
const response = await fetch('/api/user');
|
||||
if (!response.ok) return;
|
||||
|
||||
const user = await response.json();
|
||||
|
||||
// Store in localStorage for consistency
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
|
||||
const { identifyUser, trackEvent } = await import('@/components/PostHogProvider');
|
||||
identifyUser(user.id, {
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
plan: user.plan || 'FREE',
|
||||
provider: 'google',
|
||||
});
|
||||
|
||||
trackEvent(isNewUser ? 'user_signup' : 'user_login', {
|
||||
method: 'google',
|
||||
email: user.email,
|
||||
isNewUser,
|
||||
});
|
||||
|
||||
// Clean up URL params
|
||||
router.replace('/dashboard');
|
||||
} catch (error) {
|
||||
console.error('PostHog tracking error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
trackGoogleAuth();
|
||||
}
|
||||
}, [searchParams, router]);
|
||||
|
||||
// Check for successful payment and verify session
|
||||
useEffect(() => {
|
||||
const success = searchParams.get('success');
|
||||
|
|
|
|||
|
|
@ -17,7 +17,16 @@ export default function AppLayout({
|
|||
const { t } = useTranslation();
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
|
||||
const handleSignOut = () => {
|
||||
const handleSignOut = async () => {
|
||||
// Track logout event before clearing data
|
||||
try {
|
||||
const { trackEvent, resetUser } = await import('@/components/PostHogProvider');
|
||||
trackEvent('user_logout');
|
||||
resetUser(); // Reset PostHog user session
|
||||
} catch (error) {
|
||||
console.error('PostHog tracking error:', error);
|
||||
}
|
||||
|
||||
// Clear all cookies
|
||||
document.cookie.split(";").forEach(c => {
|
||||
document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
|
||||
|
|
|
|||
|
|
@ -36,6 +36,22 @@ export default function LoginPage() {
|
|||
// Store user in localStorage for client-side
|
||||
localStorage.setItem('user', JSON.stringify(data.user));
|
||||
|
||||
// Track successful login with PostHog
|
||||
try {
|
||||
const { identifyUser, trackEvent } = await import('@/components/PostHogProvider');
|
||||
identifyUser(data.user.id, {
|
||||
email: data.user.email,
|
||||
name: data.user.name,
|
||||
plan: data.user.plan || 'FREE',
|
||||
});
|
||||
trackEvent('user_login', {
|
||||
method: 'email',
|
||||
email: data.user.email,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('PostHog tracking error:', error);
|
||||
}
|
||||
|
||||
// Check for redirect parameter
|
||||
const redirectUrl = searchParams.get('redirect') || '/dashboard';
|
||||
router.push(redirectUrl);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,23 @@ export default function SignupPage() {
|
|||
// Store user in localStorage for client-side
|
||||
localStorage.setItem('user', JSON.stringify(data.user));
|
||||
|
||||
// Track successful signup with PostHog
|
||||
try {
|
||||
const { identifyUser, trackEvent } = await import('@/components/PostHogProvider');
|
||||
identifyUser(data.user.id, {
|
||||
email: data.user.email,
|
||||
name: data.user.name,
|
||||
plan: data.user.plan || 'FREE',
|
||||
signupMethod: 'email',
|
||||
});
|
||||
trackEvent('user_signup', {
|
||||
method: 'email',
|
||||
email: data.user.email,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('PostHog tracking error:', error);
|
||||
}
|
||||
|
||||
// Redirect to dashboard
|
||||
router.push('/dashboard');
|
||||
router.refresh();
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ export async function GET(request: NextRequest) {
|
|||
where: { email: userInfo.email },
|
||||
});
|
||||
|
||||
const isNewUser = !user;
|
||||
|
||||
// Create user if they don't exist
|
||||
if (!user) {
|
||||
user = await db.user.create({
|
||||
|
|
@ -148,8 +150,12 @@ export async function GET(request: NextRequest) {
|
|||
// Set authentication cookie
|
||||
cookies().set('userId', user.id, getAuthCookieOptions());
|
||||
|
||||
// Redirect to dashboard
|
||||
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_APP_URL}/dashboard`);
|
||||
// Redirect to dashboard with tracking params
|
||||
const redirectUrl = new URL(`${process.env.NEXT_PUBLIC_APP_URL}/dashboard`);
|
||||
redirectUrl.searchParams.set('authMethod', 'google');
|
||||
redirectUrl.searchParams.set('isNewUser', isNewUser.toString());
|
||||
|
||||
return NextResponse.redirect(redirectUrl.toString());
|
||||
} catch (error) {
|
||||
console.error('Google OAuth error:', error);
|
||||
return NextResponse.redirect(
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ export async function POST(request: NextRequest) {
|
|||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
plan: 'FREE',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export async function POST(request: NextRequest) {
|
|||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
user: { id: user.id, email: user.email, name: user.name }
|
||||
user: { id: user.id, email: user.email, name: user.name, plan: user.plan || 'FREE' }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
|
|
|
|||
|
|
@ -1,58 +1,74 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import posthog from 'posthog-js';
|
||||
|
||||
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
const initializationAttempted = useRef(false);
|
||||
|
||||
// Initialize PostHog once
|
||||
useEffect(() => {
|
||||
// Check if user has consented to analytics cookies
|
||||
// Prevent double initialization in React Strict Mode
|
||||
if (initializationAttempted.current) return;
|
||||
initializationAttempted.current = true;
|
||||
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
|
||||
// Only initialize PostHog if user has accepted cookies
|
||||
if (cookieConsent === 'accepted') {
|
||||
posthog.init('phc_97JBJVVQlqqiZuTVRHuBnnG9HasOv3GSsdeVjossizJ', {
|
||||
api_host: 'https://us.i.posthog.com',
|
||||
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const apiHost = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||
|
||||
if (!apiKey) {
|
||||
console.warn('PostHog API key not configured');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if already initialized (using _loaded property)
|
||||
if (!(posthog as any)._loaded) {
|
||||
posthog.init(apiKey, {
|
||||
api_host: apiHost || 'https://us.i.posthog.com',
|
||||
person_profiles: 'identified_only',
|
||||
capture_pageview: false, // We'll capture manually
|
||||
capture_pageview: false, // Manual pageview tracking
|
||||
capture_pageleave: true,
|
||||
autocapture: true,
|
||||
// Privacy-friendly settings
|
||||
respect_dnt: true,
|
||||
opt_out_capturing_by_default: false,
|
||||
loaded: (posthog) => {
|
||||
});
|
||||
|
||||
// Enable debug mode in development
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
posthog.debug();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Set initialized immediately after init
|
||||
setIsInitialized(true);
|
||||
} else {
|
||||
setIsInitialized(true); // Already loaded
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup on unmount
|
||||
return () => {
|
||||
if (cookieConsent === 'accepted') {
|
||||
posthog.opt_out_capturing();
|
||||
}
|
||||
};
|
||||
// NO cleanup function - PostHog should persist across page navigation
|
||||
}, []);
|
||||
|
||||
// Track page views
|
||||
// Track page views ONLY after PostHog is initialized
|
||||
useEffect(() => {
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
|
||||
if (cookieConsent === 'accepted' && pathname) {
|
||||
if (cookieConsent === 'accepted' && pathname && isInitialized) {
|
||||
let url = window.origin + pathname;
|
||||
if (searchParams && searchParams.toString()) {
|
||||
url = url + `?${searchParams.toString()}`;
|
||||
}
|
||||
|
||||
posthog.capture('$pageview', {
|
||||
$current_url: url,
|
||||
});
|
||||
}
|
||||
}, [pathname, searchParams]);
|
||||
}, [pathname, searchParams, isInitialized]); // Added isInitialized dependency
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
|
@ -62,7 +78,7 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
|||
*/
|
||||
export function identifyUser(userId: string, traits?: Record<string, any>) {
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
if (cookieConsent === 'accepted') {
|
||||
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
||||
posthog.identify(userId, traits);
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +88,7 @@ export function identifyUser(userId: string, traits?: Record<string, any>) {
|
|||
*/
|
||||
export function trackEvent(eventName: string, properties?: Record<string, any>) {
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
if (cookieConsent === 'accepted') {
|
||||
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
||||
posthog.capture(eventName, properties);
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +98,7 @@ export function trackEvent(eventName: string, properties?: Record<string, any>)
|
|||
*/
|
||||
export function resetUser() {
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
if (cookieConsent === 'accepted') {
|
||||
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
||||
posthog.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue