export function npsTransactionalSurvey(form: FormTs) {
// Transactional NPS Survey - Post-Purchase/Post-Transaction Feedback
// Demonstrates: RatingScale (NPS), EmojiRating, MatrixQuestion, SuggestionChips, Dropdown, dynamic styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'How Was Your Experience?',
computedValue: () => 'Your feedback helps us serve you better. This takes less than 2 minutes.',
customStyles: {
backgroundColor: '#0ea5e9',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Transaction Context
// ============================================
const contextSection = form.addSubform('context', {
title: 'About Your Transaction'
});
contextSection.addRow(row => {
row.addDropdown('transactionType', {
label: 'What type of transaction did you complete?',
options: [
{ id: 'purchase', name: 'Product Purchase' },
{ id: 'service', name: 'Service Appointment' },
{ id: 'return', name: 'Return/Exchange' },
{ id: 'support', name: 'Support Interaction' },
{ id: 'subscription', name: 'Subscription Renewal' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select transaction type',
isRequired: true
}, '1fr');
row.addDropdown('channel', {
label: 'How did you complete this transaction?',
options: [
{ id: 'online', name: 'Website' },
{ id: 'mobile', name: 'Mobile App' },
{ id: 'store', name: 'In-Store' },
{ id: 'phone', name: 'Phone' },
{ id: 'chat', name: 'Live Chat' }
],
placeholder: 'Select channel',
isRequired: true
}, '1fr');
});
// ============================================
// SECTION 2: Quick Sentiment (Emoji Rating)
// ============================================
const sentimentSection = form.addSubform('sentiment', {
title: 'Quick Reaction',
customStyles: { backgroundColor: '#f0f9ff', padding: '16px', borderRadius: '8px' }
});
sentimentSection.addRow(row => {
row.addEmojiRating('quickSentiment', {
label: 'How do you feel about your recent transaction?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 3: NPS Score
// ============================================
const npsSection = form.addSubform('npsSection', {
title: 'Recommendation Score',
customStyles: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' };
if (category === 'passive') return { backgroundColor: '#fef9c3', padding: '16px', borderRadius: '8px' };
if (category === 'detractor') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px dashed #e2e8f0' };
}
});
npsSection.addRow(row => {
row.addRatingScale('npsScore', {
preset: 'nps',
label: () => {
const type = contextSection.dropdown('transactionType')?.value();
if (type === 'purchase') return 'Based on this purchase, how likely are you to recommend us?';
if (type === 'service') return 'Based on this service, how likely are you to recommend us?';
if (type === 'return') return 'Based on your return experience, how likely are you to recommend us?';
if (type === 'support') return 'Based on this support interaction, how likely are you to recommend us?';
return 'How likely are you to recommend us based on this experience?';
},
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true,
isRequired: true
});
});
// Dynamic follow-up based on NPS category
npsSection.addSpacer({ height: '16px' });
npsSection.addRow(row => {
row.addTextarea('npsReason', {
label: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
switch (category) {
case 'promoter': return "We're thrilled! What made this transaction great?";
case 'passive': return "Thanks for your feedback! What could have made it a 9 or 10?";
case 'detractor': return "We're sorry to hear that. What went wrong?";
default: return 'Tell us more about your experience';
}
},
placeholder: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return 'Share what exceeded your expectations...';
if (category === 'passive') return 'What one thing would improve your experience...';
if (category === 'detractor') return 'Help us understand so we can make it right...';
return 'Your feedback...';
},
rows: 3,
autoExpand: true,
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
});
// ============================================
// SECTION 4: Touchpoint Ratings (Matrix)
// ============================================
const touchpointsSection = form.addSubform('touchpoints', {
title: 'Rate Your Experience',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
touchpointsSection.addRow(row => {
row.addMatrixQuestion('touchpointRatings', {
label: 'How would you rate each aspect of your transaction?',
rows: () => {
const channel = contextSection.dropdown('channel')?.value();
const baseRows = [
{ id: 'ease', label: 'Ease of transaction', isRequired: true },
{ id: 'speed', label: 'Speed/Timeliness' },
{ id: 'staff', label: 'Staff helpfulness' },
{ id: 'communication', label: 'Communication' }
];
if (channel === 'online' || channel === 'mobile') {
return [
...baseRows,
{ id: 'website', label: 'Website/App experience' },
{ id: 'checkout', label: 'Checkout process' }
];
}
if (channel === 'store') {
return [
...baseRows,
{ id: 'store_layout', label: 'Store layout' },
{ id: 'product_availability', label: 'Product availability' }
];
}
return baseRows;
},
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 5: What Influenced Your Score (Promoters)
// ============================================
const promoterSection = form.addSubform('promoterDrivers', {
title: 'What Made It Great?',
isVisible: () => npsSection.ratingScale('npsScore')?.npsCategory() === 'promoter',
customStyles: { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' }
});
promoterSection.addRow(row => {
row.addSuggestionChips('positiveDrivers', {
label: 'Select what stood out (pick up to 4)',
suggestions: [
{ id: 'quality', name: 'Product/Service quality' },
{ id: 'value', name: 'Great value' },
{ id: 'staff', name: 'Helpful staff' },
{ id: 'fast', name: 'Fast service' },
{ id: 'easy', name: 'Easy process' },
{ id: 'selection', name: 'Good selection' },
{ id: 'location', name: 'Convenient location' },
{ id: 'communication', name: 'Clear communication' }
],
max: 4,
alignment: 'center'
});
});
// ============================================
// SECTION 6: Improvement Areas (Detractors/Passives)
// ============================================
const improvementSection = form.addSubform('improvementDrivers', {
title: 'What Could We Improve?',
isVisible: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
return category === 'detractor' || category === 'passive';
},
customStyles: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'detractor') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fef9c3', padding: '16px', borderRadius: '8px' };
}
});
improvementSection.addRow(row => {
row.addSuggestionChips('improvementAreas', {
label: 'Select areas that need improvement',
suggestions: [
{ id: 'quality', name: 'Product/Service quality' },
{ id: 'price', name: 'Pricing' },
{ id: 'staff', name: 'Staff attitude' },
{ id: 'wait', name: 'Wait time' },
{ id: 'process', name: 'Complex process' },
{ id: 'availability', name: 'Availability' },
{ id: 'location', name: 'Location/Access' },
{ id: 'communication', name: 'Poor communication' }
],
alignment: 'center'
});
});
// Specific issue for detractors
improvementSection.addSpacer({ height: '12px' });
improvementSection.addRow(row => {
row.addTextarea('specificIssue', {
label: 'Please describe the specific issue (optional)',
placeholder: 'Tell us exactly what happened so we can address it...',
rows: 3,
isVisible: () => npsSection.ratingScale('npsScore')?.npsCategory() === 'detractor'
});
});
// ============================================
// SECTION 7: Follow-up Consent
// ============================================
const followupSection = form.addSubform('followup', {
title: 'Stay Connected',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
followupSection.addRow(row => {
row.addThumbRating('wouldReturn', {
label: 'Would you transact with us again?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
size: 'md',
alignment: 'center'
});
});
followupSection.addRow(row => {
row.addCheckbox('allowContact', {
label: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'detractor') return 'I would like someone to contact me about my experience';
return 'You may contact me about special offers and updates';
}
});
});
followupSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Email address',
placeholder: 'your@email.com',
isRequired: () => followupSection.checkbox('allowContact')?.value() === true,
isVisible: () => followupSection.checkbox('allowContact')?.value() === true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const score = npsSection.ratingScale('npsScore')?.value();
const category = npsSection.ratingScale('npsScore')?.npsCategory();
const sentiment = sentimentSection.emojiRating('quickSentiment')?.value();
const transactionType = contextSection.dropdown('transactionType')?.value();
const channel = contextSection.dropdown('channel')?.value();
const wouldReturn = followupSection.thumbRating('wouldReturn')?.value();
if (score === null || score === undefined) return '';
let emoji = category === 'promoter' ? '🎉' : category === 'passive' ? '🤔' : '😔';
let summary = `${emoji} Transaction Feedback Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `📊 NPS Score: ${score}/10 (${category?.charAt(0).toUpperCase()}${category?.slice(1)})\n`;
if (transactionType) {
const typeLabels: Record<string, string> = {
'purchase': 'Product Purchase',
'service': 'Service Appointment',
'return': 'Return/Exchange',
'support': 'Support Interaction',
'subscription': 'Subscription Renewal',
'other': 'Other'
};
summary += `🛒 Transaction: ${typeLabels[transactionType] || transactionType}\n`;
}
if (channel) {
const channelLabels: Record<string, string> = {
'online': 'Website',
'mobile': 'Mobile App',
'store': 'In-Store',
'phone': 'Phone',
'chat': 'Live Chat'
};
summary += `📱 Channel: ${channelLabels[channel] || channel}\n`;
}
if (sentiment) {
const sentimentLabels: Record<string, string> = {
'very-bad': '😢 Very Unsatisfied',
'bad': '😕 Unsatisfied',
'neutral': '😐 Neutral',
'good': '😊 Satisfied',
'excellent': '😃 Very Satisfied'
};
summary += `\n💭 Quick Sentiment: ${sentimentLabels[sentiment] || sentiment}`;
}
if (wouldReturn !== null && wouldReturn !== undefined) {
summary += `\n🔄 Would Return: ${wouldReturn === 'up' ? 'Yes' : 'No'}`;
}
return summary;
},
customStyles: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (category === 'promoter') {
return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #22c55e' };
} else if (category === 'passive') {
return { ...baseStyles, backgroundColor: '#fef9c3', borderLeft: '4px solid #eab308' };
} else if (category === 'detractor') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return baseStyles;
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return 'Submit & Share the Love!';
if (category === 'detractor') return 'Submit Feedback';
return 'Submit';
},
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return 'Thank you for your amazing feedback!';
if (category === 'detractor') return 'Thank you for letting us know';
return 'Thank you for your feedback!';
},
message: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return "We're so glad you had a great experience! Your recommendation means the world to us.";
if (category === 'detractor') return "We're sorry your experience wasn't up to par. A team member will review your feedback and may reach out to make things right.";
return 'Your feedback helps us improve. We appreciate you taking the time to share your thoughts.';
}
});
}