344 lines
14 KiB
TypeScript

import React, { useState } from 'react';
import { PageHeader } from '../../components/layout/PageHeader';
import { Card } from '../../components/layout/Card';
import { StepProgress } from '../../components/layout/StepProgress';
import { FormSection } from '../../components/forms/FormSection';
import { FormField } from '../../components/forms/FormField';
import { SelectField } from '../../components/forms/SelectField';
import { PhoneInput } from '../../components/forms/PhoneInput';
import { EINInput } from '../../components/forms/EINInput';
import { Button } from '../../components/shared/Button';
import { Toast } from '../../components/shared/Toast';
import { useMCPApp } from '../../hooks/useMCPApp';
import { useSmartAction } from '../../hooks/useSmartAction';
import type { RegistrationInput } from '../../../src/types';
const STEPS = [
{ label: 'Business Info', description: 'Basic details' },
{ label: 'Authorized Rep', description: 'Contact person' },
{ label: 'Address', description: 'Business location' },
{ label: 'Campaign', description: 'Use case & messages' },
{ label: 'Review', description: 'Confirm & submit' }
];
export default function RegistrationWizard() {
const { context, loading: contextLoading } = useMCPApp<{ prefillData?: RegistrationInput }>();
const { callTool, loading: submitting } = useSmartAction();
const [currentStep, setCurrentStep] = useState(0);
const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);
const [formData, setFormData] = useState<Partial<RegistrationInput>>(
context?.prefillData || {
business: {},
authorizedRep: {},
address: {},
campaign: { sampleMessages: [''], hasEmbeddedLinks: false, hasEmbeddedPhone: false },
phone: {}
} as any
);
const updateField = (section: keyof RegistrationInput, field: string, value: any) => {
setFormData(prev => ({
...prev,
[section]: {
...(prev[section] as any),
[field]: value
}
}));
};
const handleNext = () => {
if (currentStep < STEPS.length - 1) {
setCurrentStep(currentStep + 1);
}
};
const handlePrevious = () => {
if (currentStep > 0) {
setCurrentStep(currentStep - 1);
}
};
const handleSubmit = async () => {
try {
await callTool('a2p_submit_registration', formData);
setToast({ message: 'Registration submitted successfully!', type: 'success' });
setTimeout(() => {
// In production, this would close the app or navigate
window.location.reload();
}, 2000);
} catch (error) {
setToast({ message: 'Submission failed. Please try again.', type: 'error' });
}
};
if (contextLoading) {
return <div className="flex items-center justify-center h-screen">Loading...</div>;
}
return (
<div className="min-h-screen bg-gray-50">
<PageHeader
title="A2P Registration Wizard"
subtitle="Complete your brand and campaign registration"
/>
<div className="container mx-auto px-6 py-8">
<Card className="max-w-4xl mx-auto">
<div className="p-6 space-y-8">
{/* Step Progress */}
<StepProgress steps={STEPS} currentStep={currentStep} />
{/* Step Content */}
<div className="min-h-[500px]">
{currentStep === 0 && (
<FormSection title="Business Information" description="Enter your company details">
<FormField
label="Business Name"
value={(formData.business as any)?.businessName || ''}
onChange={(e) => updateField('business', 'businessName', e.target.value)}
required
/>
<SelectField
label="Business Type"
options={[
{ value: 'Corporation', label: 'Corporation' },
{ value: 'Limited Liability Corporation', label: 'LLC' },
{ value: 'Partnership', label: 'Partnership' },
{ value: 'Non-profit Corporation', label: 'Non-profit' }
]}
value={(formData.business as any)?.businessType || ''}
onChange={(e) => updateField('business', 'businessType', e.target.value)}
required
/>
<EINInput
label="EIN"
value={(formData.business as any)?.registrationNumber || ''}
onChange={(e) => updateField('business', 'registrationNumber', e.target.value)}
required
helpText="Format: XX-XXXXXXX"
/>
<FormField
label="Website URL"
type="url"
value={(formData.business as any)?.websiteUrl || ''}
onChange={(e) => updateField('business', 'websiteUrl', e.target.value)}
required
/>
<SelectField
label="Industry"
options={[
{ value: 'TECHNOLOGY', label: 'Technology' },
{ value: 'HEALTHCARE', label: 'Healthcare' },
{ value: 'FINANCIAL', label: 'Financial' },
{ value: 'RETAIL', label: 'Retail' },
{ value: 'EDUCATION', label: 'Education' }
]}
value={(formData.business as any)?.businessIndustry || ''}
onChange={(e) => updateField('business', 'businessIndustry', e.target.value)}
required
/>
<SelectField
label="Company Type"
options={[
{ value: 'private', label: 'Private' },
{ value: 'public', label: 'Public' },
{ value: 'non-profit', label: 'Non-profit' },
{ value: 'government', label: 'Government' }
]}
value={(formData.business as any)?.companyType || ''}
onChange={(e) => updateField('business', 'companyType', e.target.value)}
required
/>
</FormSection>
)}
{currentStep === 1 && (
<FormSection title="Authorized Representative" description="Primary contact for this registration">
<FormField
label="First Name"
value={(formData.authorizedRep as any)?.firstName || ''}
onChange={(e) => updateField('authorizedRep', 'firstName', e.target.value)}
required
/>
<FormField
label="Last Name"
value={(formData.authorizedRep as any)?.lastName || ''}
onChange={(e) => updateField('authorizedRep', 'lastName', e.target.value)}
required
/>
<FormField
label="Business Title"
value={(formData.authorizedRep as any)?.businessTitle || ''}
onChange={(e) => updateField('authorizedRep', 'businessTitle', e.target.value)}
required
/>
<SelectField
label="Job Position"
options={[
{ value: 'CEO', label: 'CEO' },
{ value: 'CFO', label: 'CFO' },
{ value: 'Director', label: 'Director' },
{ value: 'GM', label: 'General Manager' },
{ value: 'VP', label: 'Vice President' }
]}
value={(formData.authorizedRep as any)?.jobPosition || ''}
onChange={(e) => updateField('authorizedRep', 'jobPosition', e.target.value)}
required
/>
<PhoneInput
label="Phone Number"
value={(formData.authorizedRep as any)?.phoneNumber || ''}
onChange={(e) => updateField('authorizedRep', 'phoneNumber', e.target.value)}
required
/>
<FormField
label="Email"
type="email"
value={(formData.authorizedRep as any)?.email || ''}
onChange={(e) => updateField('authorizedRep', 'email', e.target.value)}
required
/>
</FormSection>
)}
{currentStep === 2 && (
<FormSection title="Business Address" description="Your primary business location">
<FormField
label="Street Address"
value={(formData.address as any)?.street || ''}
onChange={(e) => updateField('address', 'street', e.target.value)}
required
className="col-span-2"
/>
<FormField
label="City"
value={(formData.address as any)?.city || ''}
onChange={(e) => updateField('address', 'city', e.target.value)}
required
/>
<FormField
label="State"
value={(formData.address as any)?.region || ''}
onChange={(e) => updateField('address', 'region', e.target.value)}
required
maxLength={2}
placeholder="CA"
/>
<FormField
label="ZIP Code"
value={(formData.address as any)?.postalCode || ''}
onChange={(e) => updateField('address', 'postalCode', e.target.value)}
required
/>
<FormField
label="Country"
value={(formData.address as any)?.isoCountry || 'US'}
onChange={(e) => updateField('address', 'isoCountry', e.target.value)}
required
maxLength={2}
/>
</FormSection>
)}
{currentStep === 3 && (
<FormSection title="Campaign Information" description="Describe your messaging use case">
<SelectField
label="Use Case"
options={[
{ value: 'ACCOUNT_NOTIFICATION', label: 'Account Notifications' },
{ value: 'CUSTOMER_CARE', label: 'Customer Care' },
{ value: 'DELIVERY_NOTIFICATION', label: 'Delivery Notifications' },
{ value: 'FRAUD_ALERT', label: 'Fraud Alerts' },
{ value: 'MARKETING', label: 'Marketing' },
{ value: 'SECURITY_ALERT', label: 'Security Alerts' }
]}
value={(formData.campaign as any)?.useCase || ''}
onChange={(e) => updateField('campaign', 'useCase', e.target.value)}
required
className="col-span-2"
/>
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">
Description <span className="text-red-500">*</span>
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#667eea]"
rows={4}
value={(formData.campaign as any)?.description || ''}
onChange={(e) => updateField('campaign', 'description', e.target.value)}
placeholder="Explain what messages you send and why..."
/>
</div>
<SelectField
label="Opt-In Type"
options={[
{ value: 'WEB_FORM', label: 'Web Form' },
{ value: 'VERBAL', label: 'Verbal' },
{ value: 'VIA_TEXT', label: 'Via Text' },
{ value: 'PAPER_FORM', label: 'Paper Form' }
]}
value={(formData.campaign as any)?.optInType || ''}
onChange={(e) => updateField('campaign', 'optInType', e.target.value)}
required
/>
</FormSection>
)}
{currentStep === 4 && (
<div className="space-y-6">
<h3 className="text-xl font-semibold">Review & Submit</h3>
<div className="bg-gray-50 rounded-lg p-6 space-y-4">
<div>
<h4 className="font-semibold text-gray-700">Business</h4>
<p>{(formData.business as any)?.businessName}</p>
</div>
<div>
<h4 className="font-semibold text-gray-700">Authorized Rep</h4>
<p>{(formData.authorizedRep as any)?.firstName} {(formData.authorizedRep as any)?.lastName}</p>
</div>
<div>
<h4 className="font-semibold text-gray-700">Use Case</h4>
<p>{(formData.campaign as any)?.useCase}</p>
</div>
</div>
</div>
)}
</div>
{/* Navigation */}
<div className="flex items-center justify-between pt-6 border-t border-gray-200">
<Button
variant="ghost"
onClick={handlePrevious}
disabled={currentStep === 0}
>
Previous
</Button>
{currentStep < STEPS.length - 1 ? (
<Button onClick={handleNext}>
Next
</Button>
) : (
<Button onClick={handleSubmit} loading={submitting} variant="success">
Submit Registration
</Button>
)}
</div>
</div>
</Card>
</div>
{toast && (
<Toast
message={toast.message}
type={toast.type}
onClose={() => setToast(null)}
/>
)}
</div>
);
}