analytics/examples/funnel-tracking/SignupFlow.tsx
2026-01-29 08:20:58 -08:00

220 lines
7.5 KiB
TypeScript

/**
* SignupFlow - Example multi-step signup with funnel tracking
*
* This demonstrates how to integrate funnel tracking into a real component.
*/
import { useState, useEffect } from 'react';
import { useSignupFunnel } from './use-signup-funnel';
// ─────────────────────────────────────────────────────────────────────────────
// Types
// ─────────────────────────────────────────────────────────────────────────────
type Step = 'email' | 'verify' | 'profile' | 'complete';
interface FormData {
email: string;
code: string;
name: string;
company: string;
}
// ─────────────────────────────────────────────────────────────────────────────
// Component
// ─────────────────────────────────────────────────────────────────────────────
export function SignupFlow() {
const [step, setStep] = useState<Step>('email');
const [formData, setFormData] = useState<FormData>({
email: '',
code: '',
name: '',
company: '',
});
const [isLoading, setIsLoading] = useState(false);
// Initialize funnel tracking
const { startSignup, trackStep, completeSignup, cancelSignup } = useSignupFunnel({
source: 'signup-page',
});
// Start funnel on mount
useEffect(() => {
startSignup();
}, [startSignup]);
// ─────────────────────────────────────────────────────────────────────────────
// Step Handlers
// ─────────────────────────────────────────────────────────────────────────────
const handleEmailSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Send verification email (your API)
await fetch('/api/auth/send-code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: formData.email }),
});
// Track funnel step
const emailDomain = formData.email.split('@')[1];
trackStep('email_entered', {
email_domain: emailDomain,
is_business_email: !['gmail.com', 'yahoo.com', 'hotmail.com'].includes(emailDomain),
});
setStep('verify');
} catch (error) {
console.error('Failed to send verification email:', error);
} finally {
setIsLoading(false);
}
};
const handleVerifySubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Verify code (your API)
await fetch('/api/auth/verify-code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: formData.email, code: formData.code }),
});
// Track funnel step
trackStep('email_verified', { verification_method: 'code' });
setStep('profile');
} catch (error) {
console.error('Verification failed:', error);
} finally {
setIsLoading(false);
}
};
const handleProfileSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Create account (your API)
const response = await fetch('/api/auth/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
const user = await response.json();
// Track profile creation
trackStep('profile_created', {
has_company: Boolean(formData.company),
});
// Complete funnel with user ID
completeSignup(user.id);
setStep('complete');
} catch (error) {
console.error('Signup failed:', error);
} finally {
setIsLoading(false);
}
};
const handleCancel = () => {
cancelSignup('user_clicked_cancel');
// Navigate away
window.location.href = '/';
};
// ─────────────────────────────────────────────────────────────────────────────
// Render
// ─────────────────────────────────────────────────────────────────────────────
return (
<div className="signup-flow">
<div className="progress">
Step {['email', 'verify', 'profile', 'complete'].indexOf(step) + 1} of 4
</div>
{step === 'email' && (
<form onSubmit={handleEmailSubmit}>
<h2>Create your account</h2>
<input
type="email"
placeholder="Enter your email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
required
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Sending...' : 'Continue'}
</button>
<button type="button" onClick={handleCancel}>
Cancel
</button>
</form>
)}
{step === 'verify' && (
<form onSubmit={handleVerifySubmit}>
<h2>Verify your email</h2>
<p>We sent a code to {formData.email}</p>
<input
type="text"
placeholder="Enter verification code"
value={formData.code}
onChange={(e) => setFormData({ ...formData, code: e.target.value })}
required
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Verifying...' : 'Verify'}
</button>
<button type="button" onClick={() => setStep('email')}>
Back
</button>
</form>
)}
{step === 'profile' && (
<form onSubmit={handleProfileSubmit}>
<h2>Tell us about yourself</h2>
<input
type="text"
placeholder="Your name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
required
/>
<input
type="text"
placeholder="Company (optional)"
value={formData.company}
onChange={(e) => setFormData({ ...formData, company: e.target.value })}
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Creating account...' : 'Create Account'}
</button>
<button type="button" onClick={() => setStep('verify')}>
Back
</button>
</form>
)}
{step === 'complete' && (
<div className="success">
<h2>🎉 Welcome aboard!</h2>
<p>Your account has been created successfully.</p>
<a href="/dashboard">Go to Dashboard</a>
</div>
)}
</div>
);
}