export function escalationFeedbackSurvey(form: FormTs) {
// Escalation Resolution Feedback Survey
// Demonstrates: Multi-page wizard, StarRating, ThumbRating, Slider, MatrixQuestion, EmojiRating
// Advanced: Conditional visibility, Dynamic labels, Timeline tracking, Resolution assessment
// ============================================
// MULTI-PAGE WIZARD STRUCTURE
// ============================================
const pages = form.addPages('escalationPages', { heightMode: 'tallest-page' });
// ============================================
// PAGE 1: Resolution Outcome
// ============================================
const page1 = pages.addPage('outcome');
page1.addRow(row => {
row.addTextPanel('header', {
label: 'Escalation Resolution Feedback',
computedValue: () => 'Your issue was recently escalated. Please tell us about your experience.',
customStyles: {
backgroundColor: '#7c3aed',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
const outcomeSection = page1.addSubform('outcomeSection', {
title: 'Resolution Outcome'
});
outcomeSection.addRow(row => {
row.addThumbRating('wasResolved', {
label: 'Was your issue fully resolved?',
showLabels: true,
upLabel: 'Yes, resolved',
downLabel: 'No, not resolved',
size: 'lg',
alignment: 'center'
});
});
outcomeSection.addSpacer({ height: '16px' });
// Conditional: If not resolved
outcomeSection.addRow(row => {
row.addTextarea('unresolvedDetails', {
label: 'What is still unresolved?',
placeholder: 'Please describe what aspects remain unaddressed...',
rows: 3,
autoExpand: true,
isVisible: () => outcomeSection.thumbRating('wasResolved')?.value() === 'down',
isRequired: () => outcomeSection.thumbRating('wasResolved')?.value() === 'down'
});
});
// Resolution Quality (for resolved issues)
outcomeSection.addRow(row => {
row.addRatingScale('resolutionQuality', {
preset: 'satisfaction',
label: 'How satisfied are you with the resolution quality?',
size: 'md',
alignment: 'center',
isVisible: () => outcomeSection.thumbRating('wasResolved')?.value() === 'up'
});
});
// ============================================
// PAGE 2: Timeline & Process
// ============================================
const page2 = pages.addPage('timeline');
page2.addRow(row => {
row.addTextPanel('timelineHeader', {
label: 'Timeline & Process',
customStyles: {
backgroundColor: '#f1f5f9',
padding: '16px',
borderRadius: '8px',
textAlign: 'center',
fontWeight: 'bold'
}
});
});
const timelineSection = page2.addSubform('timelineSection', {
title: 'Response Timeline'
});
timelineSection.addRow(row => {
row.addSlider('daysToResolve', {
label: 'How many days did it take to resolve your escalation?',
min: 0,
max: 30,
step: 1,
showValue: true,
unit: 'days',
defaultValue: 3
});
});
timelineSection.addRow(row => {
row.addRatingScale('timelineSatisfaction', {
preset: 'satisfaction',
label: 'How satisfied are you with the resolution time?',
size: 'md',
alignment: 'center'
});
});
timelineSection.addSpacer({ height: '16px' });
timelineSection.addRow(row => {
row.addRadioButton('keptInformed', {
label: 'Were you kept informed about progress?',
options: [
{ id: 'always', name: 'Yes, regularly updated' },
{ id: 'sometimes', name: 'Occasionally updated' },
{ id: 'rarely', name: 'Rarely heard anything' },
{ id: 'never', name: 'No updates until resolved' }
],
orientation: 'vertical'
});
});
// ============================================
// PAGE 3: Staff & Handling
// ============================================
const page3 = pages.addPage('staff');
page3.addRow(row => {
row.addTextPanel('staffHeader', {
label: 'Staff & Handling Quality',
customStyles: {
backgroundColor: '#f1f5f9',
padding: '16px',
borderRadius: '8px',
textAlign: 'center',
fontWeight: 'bold'
}
});
});
const staffSection = page3.addSubform('staffSection', {
title: 'Escalation Specialist Performance'
});
staffSection.addRow(row => {
row.addStarRating('specialistKnowledge', {
label: 'Technical Knowledge',
tooltip: 'How knowledgeable was the specialist about your issue?',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'left'
}, '1fr');
row.addStarRating('specialistProfessionalism', {
label: 'Professionalism',
tooltip: 'How professional and courteous was their interaction?',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'left'
}, '1fr');
});
staffSection.addRow(row => {
row.addStarRating('specialistOwnership', {
label: 'Ownership & Follow-through',
tooltip: 'Did they take full ownership and follow through?',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'left'
}, '1fr');
row.addStarRating('specialistEmpathy', {
label: 'Empathy & Understanding',
tooltip: 'Did they understand and acknowledge your frustration?',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'left'
}, '1fr');
});
// ============================================
// PAGE 4: Process Assessment
// ============================================
const page4 = pages.addPage('process');
page4.addRow(row => {
row.addTextPanel('processHeader', {
label: 'Process Assessment',
customStyles: {
backgroundColor: '#f1f5f9',
padding: '16px',
borderRadius: '8px',
textAlign: 'center',
fontWeight: 'bold'
}
});
});
const processSection = page4.addSubform('processSection', {
title: 'Escalation Process Evaluation'
});
processSection.addRow(row => {
row.addMatrixQuestion('processMatrix', {
label: 'Rate each aspect of the escalation process:',
rows: [
{ id: 'easeOfEscalation', label: 'Ease of escalating', description: 'How easy was it to escalate?' },
{ id: 'handoffQuality', label: 'Handoff quality', description: 'Information transfer between agents' },
{ id: 'noRepeat', label: 'No need to repeat', description: 'Did you have to re-explain your issue?' },
{ id: 'fairTreatment', label: 'Fair treatment', description: 'Were you treated fairly throughout?' },
{ id: 'appropriateCompensation', label: 'Compensation (if any)', description: 'Was any offered compensation appropriate?' }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' },
{ id: 'na', label: 'N/A' }
],
selectionMode: 'single',
striped: true,
fullWidth: true
});
});
processSection.addSpacer({ height: '20px' });
processSection.addRow(row => {
row.addRadioButton('wasEscalationNecessary', {
label: 'In hindsight, was escalation necessary?',
options: [
{ id: 'yes', name: 'Yes, it needed senior attention' },
{ id: 'maybe', name: 'It could have been resolved earlier' },
{ id: 'no', name: 'No, first-line support should have handled it' }
],
orientation: 'vertical'
});
});
// ============================================
// PAGE 5: Improvements & Summary
// ============================================
const page5 = pages.addPage('improvements');
page5.addRow(row => {
row.addTextPanel('improvementHeader', {
label: 'Improvements & Final Thoughts',
customStyles: {
backgroundColor: '#f1f5f9',
padding: '16px',
borderRadius: '8px',
textAlign: 'center',
fontWeight: 'bold'
}
});
});
const improvementsSection = page5.addSubform('improvementsSection', {
title: 'What Could Be Better?'
});
improvementsSection.addRow(row => {
row.addCheckboxList('improvementAreas', {
label: 'What aspects of the escalation process could be improved?',
options: [
{ id: 'fasterResponse', name: 'Faster initial response' },
{ id: 'betterCommunication', name: 'Better status updates' },
{ id: 'noRepeat', name: 'Not having to repeat my issue' },
{ id: 'singleContact', name: 'Single point of contact' },
{ id: 'moreTechnical', name: 'More technically skilled staff' },
{ id: 'clearTimeline', name: 'Clear timeline expectations' },
{ id: 'betterCompensation', name: 'Better compensation for inconvenience' },
{ id: 'easierEscalation', name: 'Easier escalation process' }
],
orientation: 'vertical'
});
});
improvementsSection.addSpacer({ height: '16px' });
improvementsSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Any additional feedback or suggestions?',
placeholder: 'Share any other thoughts about your escalation experience...',
rows: 3,
autoExpand: true
});
});
// Overall Experience
const overallSection = page5.addSubform('overallSection', {
title: 'Overall Experience'
});
overallSection.addRow(row => {
row.addEmojiRating('overallFeeling', {
label: 'How do you feel about your escalation experience overall?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
overallSection.addSpacer({ height: '16px' });
overallSection.addRow(row => {
row.addRatingScale('recommendCompany', {
preset: 'nps',
label: 'After this experience, how likely are you to continue using our services?',
showCategoryLabel: true,
showSegmentColors: true,
size: 'sm',
alignment: 'center'
});
});
// ============================================
// SUMMARY SECTION
// ============================================
const summarySection = page5.addSubform('summarySection', {
title: 'Your Feedback Summary',
isVisible: () => outcomeSection.thumbRating('wasResolved')?.value() != null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const wasResolved = outcomeSection.thumbRating('wasResolved')?.value();
const resolutionQuality = outcomeSection.ratingScale('resolutionQuality')?.value();
const days = timelineSection.slider('daysToResolve')?.value();
const timelineSat = timelineSection.ratingScale('timelineSatisfaction')?.value();
const knowledge = staffSection.starRating('specialistKnowledge')?.value();
const professionalism = staffSection.starRating('specialistProfessionalism')?.value();
const ownership = staffSection.starRating('specialistOwnership')?.value();
const empathy = staffSection.starRating('specialistEmpathy')?.value();
const feeling = overallSection.emojiRating('overallFeeling')?.value();
const recommend = overallSection.ratingScale('recommendCompany')?.value();
let emoji = wasResolved === 'up' ? '✅' : '⚠️';
let summary = `${emoji} Escalation Feedback Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `📋 Resolution: ${wasResolved === 'up' ? 'Resolved' : 'Not Resolved'}\n`;
if (resolutionQuality != null) {
summary += `📊 Quality Rating: ${resolutionQuality}/5\n`;
}
if (days != null) {
summary += `\n⏱️ Resolution Time: ${days} days\n`;
}
if (timelineSat != null) {
summary += `📈 Timeline Satisfaction: ${timelineSat}/5\n`;
}
// Staff ratings
const staffScores = [knowledge, professionalism, ownership, empathy].filter(s => s != null);
if (staffScores.length > 0) {
const avgStaff = (staffScores.reduce((a, b) => a + (b ?? 0), 0) / staffScores.length).toFixed(1);
summary += `\n👤 Specialist Avg: ${avgStaff}/5`;
if (knowledge != null) summary += `\n • Knowledge: ${knowledge}/5`;
if (professionalism != null) summary += `\n • Professionalism: ${professionalism}/5`;
if (ownership != null) summary += `\n • Ownership: ${ownership}/5`;
if (empathy != null) summary += `\n • Empathy: ${empathy}/5`;
}
if (feeling) {
const moodLabels: Record<string, string> = {
'very-bad': 'Very Dissatisfied',
'bad': 'Dissatisfied',
'neutral': 'Neutral',
'good': 'Satisfied',
'excellent': 'Very Satisfied'
};
summary += `\n\n💭 Overall Feeling: ${moodLabels[feeling] || feeling}`;
}
if (recommend != null) {
summary += `\n🔄 Continue Using: ${recommend}/10`;
}
return summary;
},
customStyles: () => {
const wasResolved = outcomeSection.thumbRating('wasResolved')?.value();
const baseStyles = {
padding: '20px',
borderRadius: '10px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px',
lineHeight: '1.6'
};
if (wasResolved === 'up') {
return { ...baseStyles, backgroundColor: '#ecfdf5', borderLeft: '4px solid #10b981' };
} else if (wasResolved === 'down') {
return { ...baseStyles, backgroundColor: '#fef2f2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #94a3b8' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Escalation Feedback'
});
form.configureCompletionScreen({
type: 'text',
title: () => {
const wasResolved = outcomeSection.thumbRating('wasResolved')?.value();
if (wasResolved === 'down') {
return 'We Hear You';
}
return 'Thank You for Your Feedback';
},
message: () => {
const wasResolved = outcomeSection.thumbRating('wasResolved')?.value();
if (wasResolved === 'down') {
return 'We are sorry your issue remains unresolved. A senior manager will contact you within 24 hours to ensure we address this properly.';
}
return 'Your feedback helps us improve our escalation process. We appreciate you taking the time to share your experience with us.';
}
});
}