257 lines
8.5 KiB
TypeScript

import React from 'react';
import { FormSection } from '../../../components/forms/FormSection';
import { FormField } from '../../../components/forms/FormField';
import { SelectField } from '../../../components/forms/SelectField';
import { Button } from '../../../components/shared/Button';
const useCases = [
'MARKETING', 'CUSTOMER_CARE', 'MIXED', 'ACCOUNT_NOTIFICATION', 'DELIVERY_NOTIFICATION',
'FRAUD_ALERT', 'HIGHER_EDUCATION', 'LOW_VOLUME', 'POLITICAL', 'POLLING_VOTING',
'PUBLIC_SERVICE_ANNOUNCEMENT', 'SECURITY_ALERT',
];
const optInTypes = ['WEB_FORM', 'VERBAL', 'PAPER_FORM', 'VIA_TEXT', 'MOBILE_QR_CODE', 'OTHER'];
interface CampaignDetailsStepProps {
data: any;
errors: Record<string, string>;
onChange: (data: any) => void;
}
export function CampaignDetailsStep({ data, errors, onChange }: CampaignDetailsStepProps) {
const addSampleMessage = () => {
if (data.sampleMessages.length < 5) {
onChange({ sampleMessages: [...data.sampleMessages, ''] });
}
};
const removeSampleMessage = (index: number) => {
onChange({
sampleMessages: data.sampleMessages.filter((_: any, i: number) => i !== index),
});
};
const updateSampleMessage = (index: number, value: string) => {
const updated = [...data.sampleMessages];
updated[index] = value;
onChange({ sampleMessages: updated });
};
return (
<div>
<FormSection
title="Campaign Details"
description="Describe your messaging campaign"
>
<SelectField
label="Use Case"
name="useCase"
value={data.useCase}
onChange={(v) => onChange({ useCase: v })}
options={useCases}
error={errors.useCase}
helpText="Primary purpose of your messages"
required
/>
<div>
<label
style={{
display: 'block',
fontSize: 'var(--font-size-sm)',
fontWeight: 600,
color: 'var(--color-text-primary)',
marginBottom: 'var(--spacing-2)',
}}
>
Campaign Description *
</label>
<textarea
value={data.description}
onChange={(e) => onChange({ description: e.target.value })}
placeholder="Describe what messages you'll send and why users would want them..."
rows={4}
style={{
width: '100%',
padding: 'var(--spacing-3)',
fontSize: 'var(--font-size-base)',
border: `1px solid ${errors.description ? 'var(--color-error)' : 'var(--color-border-primary)'}`,
borderRadius: 'var(--border-radius-md)',
}}
/>
{errors.description && (
<div style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-error)', marginTop: 'var(--spacing-1)' }}>
{errors.description}
</div>
)}
</div>
<div>
<label
style={{
display: 'block',
fontSize: 'var(--font-size-sm)',
fontWeight: 600,
color: 'var(--color-text-primary)',
marginBottom: 'var(--spacing-2)',
}}
>
Sample Messages * (1-5 examples)
</label>
{data.sampleMessages.map((msg: string, index: number) => (
<div key={index} style={{ marginBottom: 'var(--spacing-3)' }}>
<div style={{ display: 'flex', gap: 'var(--spacing-2)', marginBottom: 'var(--spacing-1)' }}>
<textarea
value={msg}
onChange={(e) => updateSampleMessage(index, e.target.value)}
placeholder={`Sample message ${index + 1}...`}
rows={2}
style={{ flex: 1 }}
/>
{data.sampleMessages.length > 1 && (
<Button variant="danger" size="sm" onClick={() => removeSampleMessage(index)}>
Remove
</Button>
)}
</div>
<div style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-tertiary)' }}>
{msg.length} characters
</div>
</div>
))}
{data.sampleMessages.length < 5 && (
<Button variant="secondary" size="sm" onClick={addSampleMessage}>
+ Add Sample Message
</Button>
)}
{errors.sampleMessages && (
<div style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-error)', marginTop: 'var(--spacing-1)' }}>
{errors.sampleMessages}
</div>
)}
</div>
<div>
<label
style={{
display: 'block',
fontSize: 'var(--font-size-sm)',
fontWeight: 600,
color: 'var(--color-text-primary)',
marginBottom: 'var(--spacing-2)',
}}
>
Message Flow *
</label>
<textarea
value={data.messageFlow}
onChange={(e) => onChange({ messageFlow: e.target.value })}
placeholder="Describe how users opt in to receive your messages..."
rows={3}
style={{
width: '100%',
padding: 'var(--spacing-3)',
fontSize: 'var(--font-size-base)',
border: `1px solid ${errors.messageFlow ? 'var(--color-error)' : 'var(--color-border-primary)'}`,
borderRadius: 'var(--border-radius-md)',
}}
/>
{errors.messageFlow && (
<div style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-error)', marginTop: 'var(--spacing-1)' }}>
{errors.messageFlow}
</div>
)}
</div>
<SelectField
label="Opt-In Type"
name="optInType"
value={data.optInType}
onChange={(v) => onChange({ optInType: v })}
options={optInTypes}
error={errors.optInType}
required
/>
<FormField
label="Opt-In Confirmation Message"
name="optInMessage"
value={data.optInMessage}
onChange={(v) => onChange({ optInMessage: v })}
placeholder="Thanks for subscribing! Reply STOP to opt out."
error={errors.optInMessage}
helpText="Sent after user opts in"
required
/>
<FormField
label="Opt-Out Message"
name="optOutMessage"
value={data.optOutMessage}
onChange={(v) => onChange({ optOutMessage: v })}
placeholder="You've been unsubscribed. Reply START to rejoin."
error={errors.optOutMessage}
helpText="Response to STOP"
required
/>
<FormField
label="Help Message"
name="helpMessage"
value={data.helpMessage}
onChange={(v) => onChange({ helpMessage: v })}
placeholder="For support, contact us at help@example.com or reply STOP to unsubscribe."
error={errors.helpMessage}
helpText="Response to HELP"
required
/>
<div>
<label
style={{
display: 'block',
fontSize: 'var(--font-size-sm)',
fontWeight: 600,
color: 'var(--color-text-primary)',
marginBottom: 'var(--spacing-3)',
}}
>
Message Content
</label>
<label
style={{
display: 'flex',
alignItems: 'center',
gap: 'var(--spacing-2)',
marginBottom: 'var(--spacing-2)',
cursor: 'pointer',
}}
>
<input
type="checkbox"
checked={data.hasEmbeddedLinks}
onChange={(e) => onChange({ hasEmbeddedLinks: e.target.checked })}
/>
<span style={{ fontSize: 'var(--font-size-sm)' }}>Messages contain links/URLs</span>
</label>
<label
style={{
display: 'flex',
alignItems: 'center',
gap: 'var(--spacing-2)',
cursor: 'pointer',
}}
>
<input
type="checkbox"
checked={data.hasEmbeddedPhone}
onChange={(e) => onChange({ hasEmbeddedPhone: e.target.checked })}
/>
<span style={{ fontSize: 'var(--font-size-sm)' }}>Messages contain phone numbers</span>
</label>
</div>
</FormSection>
</div>
);
}