export function cesInteractionSurvey(form: FormTs) {
// Post-Interaction CES Survey
// Measures customer effort after support interactions
// Demonstrates: RatingScale (CES), ThumbRating, StarRating, EmojiRating, MatrixQuestion, SuggestionChips, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'How Was Your Support Experience?',
computedValue: () => 'We want to make getting help as easy as possible. Your feedback helps us improve.',
customStyles: {
backgroundColor: '#0891b2',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Customer Effort Score
// ============================================
const cesSection = form.addSubform('cesSection', {
title: 'Effort Assessment',
customStyles: () => {
const score = cesSection.ratingScale('effortScore')?.value();
if (score !== null && score !== undefined) {
if (score >= 6) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (score >= 4) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
cesSection.addRow(row => {
row.addRatingScale('effortScore', {
preset: 'ces',
label: 'How easy was it to get your issue resolved?',
lowLabel: 'Very Difficult',
highLabel: 'Very Easy',
size: 'lg',
isRequired: true
});
});
// Effort level indicator
cesSection.addRow(row => {
row.addTextPanel('effortIndicator', {
label: '',
computedValue: () => {
const score = cesSection.ratingScale('effortScore')?.value();
if (score === null || score === undefined) return '';
if (score >= 6) return '🎉 Great! We made it easy for you.';
if (score >= 4) return '🤔 We can do better. Tell us more.';
return '😟 We\'re sorry it was difficult. Help us improve.';
},
customStyles: () => {
const score = cesSection.ratingScale('effortScore')?.value();
const baseStyles = { textAlign: 'center', padding: '12px', borderRadius: '6px', fontWeight: 'bold' };
if (score !== null && score !== undefined) {
if (score >= 6) return { ...baseStyles, backgroundColor: '#10b981', color: 'white' };
if (score >= 4) return { ...baseStyles, backgroundColor: '#f59e0b', color: 'white' };
return { ...baseStyles, backgroundColor: '#ef4444', color: 'white' };
}
return { ...baseStyles, display: 'none' };
},
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
});
// ============================================
// SECTION 2: Quick Resolution Check
// ============================================
const resolutionSection = form.addSubform('resolutionSection', {
title: 'Resolution Status',
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
resolutionSection.addRow(row => {
row.addThumbRating('issueResolved', {
label: 'Was your issue resolved?',
showLabels: true,
upLabel: 'Yes, resolved',
downLabel: 'No, still open',
size: 'lg',
alignment: 'center'
});
});
// Conditional: Issue not resolved
resolutionSection.addRow(row => {
row.addTextarea('unresolvedDetails', {
label: 'Please tell us what\'s still pending',
placeholder: 'Describe what wasn\'t resolved...',
rows: 3,
isVisible: () => resolutionSection.thumbRating('issueResolved')?.value() === 'down',
isRequired: () => resolutionSection.thumbRating('issueResolved')?.value() === 'down'
});
});
// ============================================
// SECTION 3: Agent Rating (if resolved)
// ============================================
const agentSection = form.addSubform('agentSection', {
title: 'Rate Your Support Agent',
isVisible: () => resolutionSection.thumbRating('issueResolved')?.value() === 'up',
customStyles: { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' }
});
agentSection.addRow(row => {
row.addStarRating('agentRating', {
label: 'How would you rate your agent\'s performance?',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
agentSection.addRow(row => {
row.addEmojiRating('agentMood', {
label: 'How did the agent make you feel?',
preset: 'mood',
size: 'md',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 4: Effort Drivers (for high effort)
// ============================================
const effortDriversSection = form.addSubform('effortDrivers', {
title: 'What Made It Difficult?',
isVisible: () => {
const score = cesSection.ratingScale('effortScore')?.value();
return score !== null && score !== undefined && score <= 4;
},
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
effortDriversSection.addRow(row => {
row.addSuggestionChips('effortFactors', {
label: 'Select all that apply',
suggestions: [
{ id: 'wait-time', name: 'Long wait time' },
{ id: 'transfers', name: 'Too many transfers' },
{ id: 'repeat', name: 'Had to repeat myself' },
{ id: 'complex', name: 'Process too complex' },
{ id: 'knowledge', name: 'Agent lacked knowledge' },
{ id: 'communication', name: 'Poor communication' },
{ id: 'policy', name: 'Inflexible policies' },
{ id: 'tech-issues', name: 'Technical issues' }
],
alignment: 'left'
});
});
effortDriversSection.addSpacer();
effortDriversSection.addRow(row => {
row.addTextarea('effortDetails', {
label: 'Please share more details about your experience',
placeholder: 'What specifically made it difficult?',
rows: 3
});
});
// ============================================
// SECTION 5: Positive Highlights (for low effort)
// ============================================
const positiveSection = form.addSubform('positiveHighlights', {
title: 'What Worked Well?',
isVisible: () => {
const score = cesSection.ratingScale('effortScore')?.value();
return score !== null && score !== undefined && score >= 5;
},
customStyles: { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' }
});
positiveSection.addRow(row => {
row.addSuggestionChips('positiveFactors', {
label: 'Select what you appreciated',
suggestions: [
{ id: 'quick', name: 'Quick resolution' },
{ id: 'first-contact', name: 'Solved first time' },
{ id: 'knowledgeable', name: 'Knowledgeable agent' },
{ id: 'friendly', name: 'Friendly service' },
{ id: 'proactive', name: 'Proactive help' },
{ id: 'clear', name: 'Clear communication' },
{ id: 'empathy', name: 'Showed empathy' },
{ id: 'follow-up', name: 'Good follow-up' }
],
alignment: 'left'
});
});
// ============================================
// SECTION 6: Interaction Details Matrix
// ============================================
const detailsSection = form.addSubform('interactionDetails', {
title: 'Rate These Aspects',
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
detailsSection.addRow(row => {
row.addMatrixQuestion('aspectRatings', {
label: '',
rows: [
{ id: 'response-time', label: 'Response time' },
{ id: 'clarity', label: 'Clarity of explanation' },
{ id: 'professionalism', label: 'Professionalism' },
{ id: 'solution-quality', label: 'Quality of solution' }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 7: Channel & Contact
// ============================================
const channelSection = form.addSubform('channelSection', {
title: 'Interaction Channel',
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
channelSection.addRow(row => {
row.addDropdown('channel', {
label: 'How did you contact us?',
options: [
{ id: 'live-chat', name: 'Live Chat' },
{ id: 'phone', name: 'Phone Call' },
{ id: 'email', name: 'Email' },
{ id: 'social', name: 'Social Media' },
{ id: 'self-service', name: 'Self-Service Portal' },
{ id: 'in-person', name: 'In Person' }
],
placeholder: 'Select channel...'
}, '1fr');
row.addTextbox('ticketNumber', {
label: 'Ticket/Case Number (optional)',
placeholder: 'e.g., #12345'
}, '1fr');
});
// ============================================
// SECTION 8: Follow-up Contact
// ============================================
const contactSection = form.addSubform('contactSection', {
title: 'Follow-up',
isVisible: () => {
const score = cesSection.ratingScale('effortScore')?.value();
return score !== null && score !== undefined && score <= 4;
}
});
contactSection.addRow(row => {
row.addCheckbox('wantsFollowUp', {
label: 'I would like someone to follow up with me about this experience'
});
});
contactSection.addRow(row => {
row.addEmail('followUpEmail', {
label: 'Email address',
placeholder: 'your@email.com',
isVisible: () => contactSection.checkbox('wantsFollowUp')?.value() === true,
isRequired: () => contactSection.checkbox('wantsFollowUp')?.value() === true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Your Feedback Summary',
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const effortScore = cesSection.ratingScale('effortScore')?.value();
const resolved = resolutionSection.thumbRating('issueResolved')?.value();
const agentRating = agentSection.starRating('agentRating')?.value();
const channel = channelSection.dropdown('channel')?.value();
const effortFactors = effortDriversSection.suggestionChips('effortFactors')?.value() || [];
const positiveFactors = positiveSection.suggestionChips('positiveFactors')?.value() || [];
if (effortScore === null || effortScore === undefined) return '';
let emoji = effortScore >= 6 ? '✨' : effortScore >= 4 ? '📊' : '⚠️';
let effortLabel = effortScore >= 6 ? 'Low Effort' : effortScore >= 4 ? 'Moderate Effort' : 'High Effort';
let summary = `${emoji} Feedback Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `📊 CES Score: ${effortScore}/7 (${effortLabel})\n`;
if (resolved) {
summary += `✅ Issue: ${resolved === 'up' ? 'Resolved' : 'Not Resolved'}\n`;
}
if (agentRating) {
summary += `⭐ Agent Rating: ${agentRating}/5 stars\n`;
}
if (channel) {
const channelLabels: Record<string, string> = {
'live-chat': 'Live Chat',
'phone': 'Phone',
'email': 'Email',
'social': 'Social Media',
'self-service': 'Self-Service',
'in-person': 'In Person'
};
summary += `📞 Channel: ${channelLabels[channel] || channel}\n`;
}
if (effortFactors.length > 0) {
summary += `\n⚠️ Difficulty factors: ${effortFactors.length} selected`;
}
if (positiveFactors.length > 0) {
summary += `\n✨ Positive factors: ${positiveFactors.length} selected`;
}
return summary;
},
customStyles: () => {
const score = cesSection.ratingScale('effortScore')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (score !== null && score !== undefined) {
if (score >= 6) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (score >= 4) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
return baseStyles;
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => cesSection.ratingScale('effortScore')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your input helps us reduce friction and improve the support experience. We appreciate you taking the time to share your thoughts.'
});
}