Paar fehler

This commit is contained in:
2026-01-22 20:09:54 +01:00
parent e44dc1c6bb
commit 59131a54f0
26 changed files with 1609 additions and 1544 deletions

View File

@@ -4,17 +4,36 @@ import { useEffect, useState, useRef } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import posthog from 'posthog-js';
export function PostHogProvider({ children }: { children: React.ReactNode }) {
import { Suspense } from 'react';
export function PostHogPageView() {
const pathname = usePathname();
const searchParams = useSearchParams();
const [isInitialized, setIsInitialized] = useState(false);
const initializationAttempted = useRef(false);
useEffect(() => {
const cookieConsent = localStorage.getItem('cookieConsent');
if (cookieConsent === 'accepted' && pathname && (posthog as any)._loaded) {
let url = window.origin + pathname;
if (searchParams && searchParams.toString()) {
url = url + `?${searchParams.toString()}`;
}
posthog.capture('$pageview', {
$current_url: url,
});
}
}, [pathname, searchParams]);
return null;
}
export function PostHogProvider({ children }: { children: React.ReactNode }) {
const [initializationAttempted, setInitializationAttempted] = useState(false);
// Initialize PostHog once
useEffect(() => {
// Prevent double initialization in React Strict Mode
if (initializationAttempted.current) return;
initializationAttempted.current = true;
if (initializationAttempted) return;
setInitializationAttempted(true);
const cookieConsent = localStorage.getItem('cookieConsent');
@@ -27,50 +46,32 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
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, // Manual pageview tracking
capture_pageview: false,
capture_pageleave: true,
autocapture: true,
respect_dnt: true,
opt_out_capturing_by_default: false,
});
// 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
}
}
}, [initializationAttempted]);
// NO cleanup function - PostHog should persist across page navigation
}, []);
// Track page views ONLY after PostHog is initialized
useEffect(() => {
const cookieConsent = localStorage.getItem('cookieConsent');
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, isInitialized]); // Added isInitialized dependency
return <>{children}</>;
return (
<>
<Suspense fallback={null}>
<PostHogPageView />
</Suspense>
{children}
</>
);
}
/**

View File

@@ -3,15 +3,12 @@
import { Suspense } from 'react';
import { ToastContainer } from '@/components/ui/Toast';
import AuthProvider from '@/components/SessionProvider';
import { PostHogProvider, PostHogPageView } from '@/components/PostHogProvider';
import { PostHogProvider } from '@/components/PostHogProvider';
import CookieBanner from '@/components/CookieBanner';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<PostHogProvider>
<Suspense fallback={null}>
<PostHogPageView />
</Suspense>
<AuthProvider>
{children}
</AuthProvider>

View File

@@ -8,6 +8,8 @@ import { Input } from '@/components/ui/Input';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { calculateContrast } from '@/lib/utils';
import { trackEvent } from '@/components/PostHogProvider';
import { useEffect } from 'react';
interface InstantGeneratorProps {
t: any; // i18n translation function
@@ -20,6 +22,18 @@ export const InstantGenerator: React.FC<InstantGeneratorProps> = ({ t }) => {
const [cornerStyle, setCornerStyle] = useState('square');
const [size, setSize] = useState(200);
useEffect(() => {
if (url) {
trackEvent('instant_qr_generated', {
url_length: url.length,
foreground: foregroundColor,
background: backgroundColor,
corner_style: cornerStyle,
size: size
});
}
}, [url, foregroundColor, backgroundColor, cornerStyle, size]);
const contrast = calculateContrast(foregroundColor, backgroundColor);
const hasGoodContrast = contrast >= 4.5;
@@ -38,6 +52,7 @@ export const InstantGenerator: React.FC<InstantGeneratorProps> = ({ t }) => {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(downloadUrl);
trackEvent('instant_qr_downloaded', { format: 'svg' });
} else {
// Convert SVG to PNG using Canvas
const canvas = document.createElement('canvas');
@@ -65,6 +80,7 @@ export const InstantGenerator: React.FC<InstantGeneratorProps> = ({ t }) => {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(downloadUrl);
trackEvent('instant_qr_downloaded', { format: 'png' });
}
});
URL.revokeObjectURL(url);