feat(analytics): implement total transparency suite and SEO metadata standardization
- Added global ScrollDepthTracker (25%, 50%, 75%, 100%) - Implemented ProductEngagementTracker for deep product analytics - Added field-level tracking to ContactForm and RequestQuoteForm - Standardized SEO metadata (canonical, alternates, x-default) across all routes - Created reusable TrackedLink and TrackedButton components for server components - Fixed 'useAnalytics' hook error in Footer.tsx by adding 'use client'
This commit is contained in:
@@ -5,6 +5,7 @@ import { useTranslations } from 'next-intl';
|
||||
import { Input, Textarea, Button } from '@/components/ui';
|
||||
import { sendContactFormAction } from '@/app/actions/contact';
|
||||
import { useAnalytics } from '@/components/analytics/useAnalytics';
|
||||
import { AnalyticsEvents } from '@/components/analytics/analytics-events';
|
||||
|
||||
interface RequestQuoteFormProps {
|
||||
productName: string;
|
||||
@@ -16,6 +17,26 @@ export default function RequestQuoteForm({ productName }: RequestQuoteFormProps)
|
||||
const [email, setEmail] = useState('');
|
||||
const [request, setRequest] = useState('');
|
||||
const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
|
||||
const [hasStarted, setHasStarted] = useState(false);
|
||||
|
||||
const handleFocus = (fieldId: string) => {
|
||||
// Initial form start
|
||||
if (!hasStarted) {
|
||||
setHasStarted(true);
|
||||
trackEvent(AnalyticsEvents.FORM_START, {
|
||||
form_id: 'quote_request_form',
|
||||
form_name: 'Product Quote Inquiry',
|
||||
product_name: productName,
|
||||
});
|
||||
}
|
||||
|
||||
// Field-level transparency
|
||||
trackEvent(AnalyticsEvents.FORM_FIELD_FOCUS, {
|
||||
form_id: 'quote_request_form',
|
||||
field_id: fieldId,
|
||||
product_name: productName,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -39,10 +60,20 @@ export default function RequestQuoteForm({ productName }: RequestQuoteFormProps)
|
||||
setEmail('');
|
||||
setRequest('');
|
||||
} else {
|
||||
trackEvent(AnalyticsEvents.FORM_ERROR, {
|
||||
form_id: 'quote_request_form',
|
||||
product_name: productName,
|
||||
error: result.error || 'submission_failed',
|
||||
});
|
||||
setStatus('error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Form submission error:', error);
|
||||
trackEvent(AnalyticsEvents.FORM_ERROR, {
|
||||
form_id: 'quote_request_form',
|
||||
product_name: productName,
|
||||
error: (error as Error).message || 'unexpected_error',
|
||||
});
|
||||
setStatus('error');
|
||||
}
|
||||
};
|
||||
@@ -131,6 +162,7 @@ export default function RequestQuoteForm({ productName }: RequestQuoteFormProps)
|
||||
required
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
onFocus={() => handleFocus('email')}
|
||||
placeholder={t('email')}
|
||||
className="h-9 text-xs !mt-0"
|
||||
/>
|
||||
@@ -143,6 +175,7 @@ export default function RequestQuoteForm({ productName }: RequestQuoteFormProps)
|
||||
rows={3}
|
||||
value={request}
|
||||
onChange={(e) => setRequest(e.target.value)}
|
||||
onFocus={() => handleFocus('request')}
|
||||
placeholder={t('message')}
|
||||
className="text-xs !mt-0"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user