/** * Enhanced Multi-Step Signup Form * Handles paid plan signups with billing information collection * Step 1: Basic user info * Step 2: Billing info (for paid plans only) * Step 3: Payment method selection (for paid plans only) */ import { useState, useEffect } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { ChevronLeftIcon, EyeCloseIcon, EyeIcon } from '../../icons'; import { ChevronRight, Check } from 'lucide-react'; import Label from '../form/Label'; import Input from '../form/input/InputField'; import Checkbox from '../form/input/Checkbox'; import Button from '../ui/button/Button'; import { useAuthStore } from '../../store/authStore'; import BillingFormStep, { BillingFormData } from '../billing/BillingFormStep'; import PaymentMethodSelect, { PaymentMethodConfig } from '../billing/PaymentMethodSelect'; interface SignUpFormEnhancedProps { planDetails?: any; planLoading?: boolean; } export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planLoading: planLoadingProp }: SignUpFormEnhancedProps) { const [currentStep, setCurrentStep] = useState(1); const [showPassword, setShowPassword] = useState(false); const [isChecked, setIsChecked] = useState(false); // Step 1: Basic user info const [formData, setFormData] = useState({ firstName: '', lastName: '', email: '', password: '', username: '', accountName: '', }); // Step 2: Billing info (for paid plans) const [billingData, setBillingData] = useState({ billing_email: '', billing_address_line1: '', billing_address_line2: '', billing_city: '', billing_state: '', billing_postal_code: '', billing_country: '', tax_id: '', }); // Step 3: Payment method const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(null); const [error, setError] = useState(''); const [planDetails, setPlanDetails] = useState(planDetailsProp || null); const [planLoading, setPlanLoading] = useState(planLoadingProp || false); const [planError, setPlanError] = useState(''); const navigate = useNavigate(); const { register, loading } = useAuthStore(); const planSlug = new URLSearchParams(window.location.search).get('plan') || ''; const paidPlans = ['starter', 'growth', 'scale']; const isPaidPlan = planSlug && paidPlans.includes(planSlug); const totalSteps = isPaidPlan ? 3 : 1; useEffect(() => { if (planDetailsProp) { setPlanDetails(planDetailsProp); setPlanLoading(!!planLoadingProp); setPlanError(''); return; } const fetchPlan = async () => { if (!planSlug) return; setPlanLoading(true); setPlanError(''); try { const API_BASE_URL = import.meta.env.VITE_BACKEND_URL || 'https://api.igny8.com/api'; const res = await fetch(`${API_BASE_URL}/v1/auth/plans/?slug=${planSlug}`); const data = await res.json(); const plan = data?.results?.[0]; if (!plan) { setPlanError('Plan not found or inactive.'); } else { const features = Array.isArray(plan.features) ? plan.features.map((f: string) => f.charAt(0).toUpperCase() + f.slice(1)) : []; setPlanDetails({ ...plan, features }); } } catch (e: any) { setPlanError('Unable to load plan details right now.'); } finally { setPlanLoading(false); } }; fetchPlan(); }, [planSlug, planDetailsProp, planLoadingProp]); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value })); }; const handleBillingChange = (field: keyof BillingFormData, value: string) => { setBillingData((prev) => ({ ...prev, [field]: value })); }; const handleNextStep = () => { setError(''); if (currentStep === 1) { // Validate step 1 if (!formData.email || !formData.password || !formData.firstName || !formData.lastName) { setError('Please fill in all required fields'); return; } if (!isChecked) { setError('Please agree to the Terms and Conditions'); return; } // Auto-fill billing email if not set if (isPaidPlan && !billingData.billing_email) { setBillingData((prev) => ({ ...prev, billing_email: formData.email })); } setCurrentStep(2); } else if (currentStep === 2) { // Validate step 2 (billing) if (!billingData.billing_email || !billingData.billing_address_line1 || !billingData.billing_city || !billingData.billing_state || !billingData.billing_postal_code || !billingData.billing_country) { setError('Please fill in all required billing fields'); return; } setCurrentStep(3); } }; const handlePrevStep = () => { setError(''); setCurrentStep((prev) => Math.max(1, prev - 1)); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); // Final validation if (!formData.email || !formData.password || !formData.firstName || !formData.lastName) { setError('Please fill in all required fields'); return; } if (!isChecked) { setError('Please agree to the Terms and Conditions'); return; } // Validate billing for paid plans if (isPaidPlan) { if (!billingData.billing_email || !billingData.billing_address_line1 || !billingData.billing_city || !billingData.billing_state || !billingData.billing_postal_code || !billingData.billing_country) { setError('Please fill in all required billing fields'); setCurrentStep(2); return; } if (!selectedPaymentMethod) { setError('Please select a payment method'); setCurrentStep(3); return; } } try { const username = formData.username || formData.email.split('@')[0]; const registerPayload: any = { email: formData.email, password: formData.password, username: username, first_name: formData.firstName, last_name: formData.lastName, account_name: formData.accountName, plan_slug: planSlug || undefined, }; // Add billing fields for paid plans if (isPaidPlan) { registerPayload.billing_email = billingData.billing_email; registerPayload.billing_address_line1 = billingData.billing_address_line1; registerPayload.billing_address_line2 = billingData.billing_address_line2 || undefined; registerPayload.billing_city = billingData.billing_city; registerPayload.billing_state = billingData.billing_state; registerPayload.billing_postal_code = billingData.billing_postal_code; registerPayload.billing_country = billingData.billing_country; registerPayload.tax_id = billingData.tax_id || undefined; registerPayload.payment_method = selectedPaymentMethod?.payment_method; } const user = await register(registerPayload) as any; const status = user?.account?.status; if (status === 'pending_payment') { navigate('/account/plans', { replace: true }); } else { navigate('/sites', { replace: true }); } } catch (err: any) { setError(err.message || 'Registration failed. Please try again.'); } }; // Render step indicator const renderStepIndicator = () => { if (!isPaidPlan) return null; return (
{[1, 2, 3].map((step) => (
{step < currentStep ? : step}
{step === 1 ? 'Account' : step === 2 ? 'Billing' : 'Payment'}
{step < 3 && (
)}
))}
); }; return (
Back to dashboard

{isPaidPlan ? `Sign Up for ${planDetails?.name || 'Paid'} Plan` : 'Start Your Free Trial'}

{isPaidPlan ? `Complete the ${totalSteps}-step process to activate your subscription.` : 'No credit card required. 1000 AI credits to get started.'}

{renderStepIndicator()} {error && (
{error}
)}
{/* Step 1: Basic Info */} {currentStep === 1 && (
setShowPassword(!showPassword)} className="absolute z-30 -translate-y-1/2 cursor-pointer right-4 top-1/2" > {showPassword ? ( ) : ( )}

By creating an account means you agree to the{' '} Terms and Conditions, and our Privacy Policy

{isPaidPlan ? ( ) : ( )}
)} {/* Step 2: Billing Info */} {currentStep === 2 && isPaidPlan && (
)} {/* Step 3: Payment Method */} {currentStep === 3 && isPaidPlan && (
)}

Already have an account?{' '} Sign In

); }