export function callCenterFeedback(form: FormTs) {
// Call Center Feedback Survey - Post-call quality assessment
// Demonstrates: StarRating x4, MatrixQuestion, RatingScale (CES), EmojiRating, ThumbRating, conditional logic
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'How Was Your Call Experience?',
computedValue: () => 'Your feedback helps us improve our phone support. This survey takes about 90 seconds.',
customStyles: {
backgroundColor: '#0f766e',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Call Context
// ============================================
const contextSection = form.addSubform('context', {
title: 'About Your Call'
});
contextSection.addRow(row => {
row.addRadioButton('callReason', {
label: 'What was the main reason for your call?',
options: [
{ id: 'billing', name: 'Billing or payment question' },
{ id: 'technical', name: 'Technical support' },
{ id: 'product', name: 'Product information' },
{ id: 'complaint', name: 'Complaint or issue' },
{ id: 'order', name: 'Order status or tracking' },
{ id: 'cancellation', name: 'Cancellation or return' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical',
isRequired: true
});
});
contextSection.addRow(row => {
row.addThumbRating('issueResolved', {
label: 'Was your issue resolved during this call?',
showLabels: true,
upLabel: 'Yes, fully resolved',
downLabel: 'No, not resolved',
alignment: 'left',
size: 'lg'
});
});
// Follow-up for unresolved issues
const unresolvedSection = form.addSubform('unresolved', {
title: 'Help Us Resolve Your Issue',
isVisible: () => contextSection.thumbRating('issueResolved')?.value() === 'down',
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
unresolvedSection.addRow(row => {
row.addRadioButton('unresolvedReason', {
label: 'Why wasn\'t your issue resolved?',
options: [
{ id: 'escalation', name: 'Needs to be escalated to another team' },
{ id: 'callback', name: 'Waiting for a callback' },
{ id: 'info-needed', name: 'I need to provide more information' },
{ id: 'agent-unable', name: 'Agent couldn\'t help with my issue' },
{ id: 'disconnected', name: 'Call was disconnected' },
{ id: 'other', name: 'Other reason' }
],
orientation: 'vertical'
});
});
unresolvedSection.addRow(row => {
row.addCheckbox('requestCallback', {
label: 'I would like a supervisor to call me back about this issue'
});
});
// ============================================
// SECTION 2: Wait Time Experience
// ============================================
const waitSection = form.addSubform('waitTime', {
title: 'Wait Time Experience'
});
waitSection.addRow(row => {
row.addRadioButton('actualWaitTime', {
label: 'Approximately how long did you wait before speaking to an agent?',
options: [
{ id: 'immediate', name: 'Less than 1 minute' },
{ id: '1-5', name: '1-5 minutes' },
{ id: '5-10', name: '5-10 minutes' },
{ id: '10-20', name: '10-20 minutes' },
{ id: 'over-20', name: 'Over 20 minutes' }
],
orientation: 'horizontal'
});
});
waitSection.addRow(row => {
row.addStarRating('waitTimeSatisfaction', {
label: 'How satisfied were you with the wait time?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
// ============================================
// SECTION 3: Agent Performance
// ============================================
const agentSection = form.addSubform('agent', {
title: 'Agent Performance'
});
agentSection.addRow(row => {
row.addTextPanel('agentInstructions', {
computedValue: () => 'Please rate your experience with the agent who helped you:',
customStyles: {
backgroundColor: '#f0fdfa',
padding: '12px',
borderRadius: '8px',
fontSize: '14px'
}
});
});
agentSection.addRow(row => {
row.addMatrixQuestion('agentAttributes', {
label: 'Rate the agent on the following:',
rows: [
{ id: 'courtesy', label: 'Courtesy & Professionalism', description: 'Polite, respectful, professional tone', isRequired: true },
{ id: 'knowledge', label: 'Product Knowledge', description: 'Understood the product/service well', isRequired: true },
{ id: 'listening', label: 'Listening Skills', description: 'Understood my issue correctly', isRequired: true },
{ id: 'clarity', label: 'Clear Communication', description: 'Explained things in a way I understood', isRequired: true },
{ id: 'efficiency', label: 'Efficiency', description: 'Handled the call without unnecessary delays', isRequired: true }
],
columns: [
{ id: '1', label: 'Poor' },
{ id: '2', label: 'Fair' },
{ id: '3', label: 'Good' },
{ id: '4', label: 'Very Good' },
{ id: '5', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
agentSection.addRow(row => {
row.addStarRating('overallAgentRating', {
label: 'Overall agent rating',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
// ============================================
// SECTION 4: Effort Score (CES)
// ============================================
const effortSection = form.addSubform('effort', {
title: 'Ease of Experience'
});
effortSection.addRow(row => {
row.addRatingScale('effortScore', {
label: 'How easy was it to get the help you needed?',
preset: 'ces',
lowLabel: 'Very Difficult',
highLabel: 'Very Easy',
size: 'md',
alignment: 'center'
});
});
effortSection.addRow(row => {
row.addRadioButton('transferCount', {
label: 'How many times were you transferred during your call?',
options: [
{ id: '0', name: 'Not transferred' },
{ id: '1', name: 'Once' },
{ id: '2', name: 'Twice' },
{ id: '3+', name: 'Three or more times' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 5: Overall Satisfaction
// ============================================
const satisfactionSection = form.addSubform('satisfaction', {
title: 'Overall Satisfaction'
});
satisfactionSection.addRow(row => {
row.addEmojiRating('overallExperience', {
label: 'How would you rate your overall call experience?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
satisfactionSection.addRow(row => {
row.addRatingScale('npsScore', {
label: 'How likely are you to recommend our support to others?',
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true
});
});
// ============================================
// SECTION 6: Feedback Based on Experience
// ============================================
// Positive experience follow-up
const positiveSection = form.addSubform('positive', {
title: 'What Went Well?',
isVisible: () => {
const emoji = satisfactionSection.emojiRating('overallExperience')?.value();
return emoji === 'good' || emoji === 'excellent';
},
customStyles: { backgroundColor: '#f0fdf4', padding: '16px', borderRadius: '8px' }
});
positiveSection.addRow(row => {
row.addSuggestionChips('positiveAspects', {
label: 'What made this a great experience? (Select all that apply)',
suggestions: [
{ id: 'fast-resolution', name: 'Quick resolution' },
{ id: 'friendly-agent', name: 'Friendly agent' },
{ id: 'knowledgeable', name: 'Knowledgeable support' },
{ id: 'short-wait', name: 'Short wait time' },
{ id: 'first-call', name: 'Fixed on first call' },
{ id: 'exceeded', name: 'Exceeded expectations' }
],
alignment: 'center'
});
});
// Negative experience follow-up
const negativeSection = form.addSubform('negative', {
title: 'What Could We Improve?',
isVisible: () => {
const emoji = satisfactionSection.emojiRating('overallExperience')?.value();
return emoji === 'very-bad' || emoji === 'bad' || emoji === 'neutral';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
negativeSection.addRow(row => {
row.addSuggestionChips('improvementAreas', {
label: 'What disappointed you? (Select all that apply)',
suggestions: [
{ id: 'long-wait', name: 'Long wait time' },
{ id: 'multiple-transfers', name: 'Too many transfers' },
{ id: 'unhelpful', name: 'Agent unhelpful' },
{ id: 'not-resolved', name: 'Issue not resolved' },
{ id: 'rude', name: 'Agent was rude' },
{ id: 'wrong-info', name: 'Wrong information given' }
],
alignment: 'center'
});
});
// ============================================
// SECTION 7: Additional Comments
// ============================================
const commentsSection = form.addSubform('comments', {
title: 'Additional Feedback'
});
commentsSection.addSpacer();
commentsSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Is there anything else you\'d like to share about your call experience?',
placeholder: 'Your detailed feedback helps us train our agents and improve our service...',
rows: 4,
autoExpand: true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Your Feedback Summary',
isVisible: () => satisfactionSection.emojiRating('overallExperience')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const callReason = contextSection.radioButton('callReason')?.value();
const resolved = contextSection.thumbRating('issueResolved')?.value();
const agentRating = agentSection.starRating('overallAgentRating')?.value();
const experience = satisfactionSection.emojiRating('overallExperience')?.value();
const effortScore = effortSection.ratingScale('effortScore')?.value();
const reasonLabels: Record<string, string> = {
'billing': 'Billing',
'technical': 'Technical Support',
'product': 'Product Info',
'complaint': 'Complaint',
'order': 'Order Status',
'cancellation': 'Cancellation',
'other': 'Other'
};
const experienceLabels: Record<string, string> = {
'very-bad': '😢 Very Poor',
'bad': '😕 Poor',
'neutral': '😐 Neutral',
'good': '😊 Good',
'excellent': '😃 Excellent'
};
let summary = `📞 Call Feedback Summary\n`;
summary += `${'═'.repeat(26)}\n\n`;
summary += `📋 Reason: ${reasonLabels[callReason || ''] || 'Not specified'}\n`;
summary += `✅ Resolved: ${resolved === 'up' ? 'Yes' : resolved === 'down' ? 'No' : 'Unknown'}\n`;
if (agentRating) {
summary += `\n⭐ Agent Rating: ${agentRating}/5 stars`;
}
if (effortScore) {
summary += `\n💪 Effort Score: ${effortScore}/7`;
}
if (experience) {
summary += `\n${experienceLabels[experience] || experience}`;
}
return summary;
},
customStyles: () => {
const resolved = contextSection.thumbRating('issueResolved')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (resolved === 'up') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (resolved === 'down') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #0f766e' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Call Feedback'
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: () => {
const resolved = contextSection.thumbRating('issueResolved')?.value();
const callback = unresolvedSection.checkbox('requestCallback')?.value();
if (resolved === 'down' && callback) {
return 'We\'re sorry your issue wasn\'t fully resolved. A supervisor will contact you within 24 hours to help resolve your concern.';
}
return 'Your feedback helps us improve our phone support quality. We appreciate you taking the time to share your experience with us.';
}
});
}