export function complaintResolutionSurvey(form: FormTs) {
// Complaint Resolution Feedback - Post-issue satisfaction survey
// Demonstrates: EmojiRating, StarRating, ThumbRating, RatingScale (CES), MatrixQuestion, RadioButton
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Complaint Resolution Feedback',
computedValue: () => 'We recently resolved an issue for you. Please share your experience with us.',
customStyles: {
backgroundColor: '#0891b2',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Overall Resolution Feeling
// ============================================
const overallSection = form.addSubform('overall', {
title: 'How Do You Feel?'
});
overallSection.addRow(row => {
row.addEmojiRating('overallFeeling', {
label: 'How do you feel about how we handled your complaint?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center',
isRequired: true
});
});
// Dynamic message based on feeling
overallSection.addRow(row => {
row.addTextPanel('feelingMessage', {
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null,
computedValue: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
if (feeling === 'excellent' || feeling === 'good') return 'We\'re glad we could help resolve your issue!';
if (feeling === 'neutral') return 'We\'d love to know how we could have done better.';
return 'We\'re sorry we didn\'t meet your expectations. Please tell us more.';
},
customStyles: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
const baseStyles = { padding: '12px', borderRadius: '8px', textAlign: 'center', marginTop: '8px' };
if (feeling === 'excellent' || feeling === 'good') return { ...baseStyles, backgroundColor: '#ecfdf5', color: '#047857' };
if (feeling === 'neutral') return { ...baseStyles, backgroundColor: '#fffbeb', color: '#b45309' };
return { ...baseStyles, backgroundColor: '#fef2f2', color: '#b91c1c' };
}
});
});
// ============================================
// SECTION 2: Resolution Details
// ============================================
const resolutionSection = form.addSubform('resolution', {
title: 'About the Resolution',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
resolutionSection.addRow(row => {
row.addRadioButton('resolutionType', {
label: 'What type of resolution did you receive?',
options: [
{ id: 'refund', name: 'Refund' },
{ id: 'replacement', name: 'Replacement' },
{ id: 'repair', name: 'Repair / Fix' },
{ id: 'credit', name: 'Store credit / Discount' },
{ id: 'explanation', name: 'Explanation / Apology' },
{ id: 'other', name: 'Other solution' }
],
orientation: 'vertical'
});
});
resolutionSection.addSpacer();
// Fairness perception
resolutionSection.addRow(row => {
row.addThumbRating('fairnessRating', {
label: 'Was the resolution fair and appropriate for your issue?',
showLabels: true,
upLabel: 'Fair',
downLabel: 'Unfair',
size: 'lg',
alignment: 'center'
});
});
// Effort score
resolutionSection.addRow(row => {
row.addRatingScale('effortScore', {
label: 'How easy was it to get your issue resolved?',
preset: 'ces',
showSegmentColors: false,
alignment: 'center'
});
});
// ============================================
// SECTION 3: Staff Handling (Positive Path)
// ============================================
const staffSection = form.addSubform('staff', {
title: 'Staff Handling',
isVisible: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
return feeling !== null;
}
});
staffSection.addRow(row => {
row.addMatrixQuestion('staffAttributes', {
label: 'Please rate the staff who handled your complaint:',
rows: [
{ id: 'responsiveness', label: 'Responsiveness', isRequired: true },
{ id: 'empathy', label: 'Empathy & Understanding', isRequired: true },
{ id: 'knowledge', label: 'Knowledge & Competence', isRequired: true },
{ id: 'communication', label: 'Communication clarity', isRequired: true },
{ id: 'ownership', label: 'Taking ownership' }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 4: Timeline
// ============================================
const timelineSection = form.addSubform('timeline', {
title: 'Resolution Timeline',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
timelineSection.addRow(row => {
row.addRadioButton('resolutionSpeed', {
label: 'How long did it take to resolve your issue?',
options: [
{ id: 'immediate', name: 'Immediately (same contact)' },
{ id: 'sameDay', name: 'Same day' },
{ id: 'nextDay', name: 'Next day' },
{ id: 'fewDays', name: '2-3 days' },
{ id: 'week', name: 'About a week' },
{ id: 'longer', name: 'More than a week' }
],
orientation: 'vertical'
});
});
timelineSection.addRow(row => {
row.addStarRating('speedSatisfaction', {
label: 'How satisfied are you with the resolution speed?',
maxStars: 5,
size: 'md',
alignment: 'center'
});
});
// ============================================
// SECTION 5: Trust Restoration
// ============================================
const trustSection = form.addSubform('trust', {
title: 'Trust & Future Relationship',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
trustSection.addRow(row => {
row.addRatingScale('trustRestored', {
label: 'Has your trust in us been restored after this experience?',
preset: 'likert-5',
lowLabel: 'Not at all',
highLabel: 'Completely',
alignment: 'center'
});
});
trustSection.addRow(row => {
row.addRadioButton('futureIntent', {
label: 'How likely are you to continue doing business with us?',
options: [
{ id: 'definitely', name: 'Definitely will continue' },
{ id: 'probably', name: 'Probably will continue' },
{ id: 'unsure', name: 'Not sure' },
{ id: 'probablyNot', name: 'Probably will not continue' },
{ id: 'definitelyNot', name: 'Definitely will not continue' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 6: Improvement Suggestions (Negative Path)
// ============================================
const improvementSection = form.addSubform('improvement', {
title: 'How Could We Have Done Better?',
isVisible: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
return feeling === 'very-bad' || feeling === 'bad' || feeling === 'neutral';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
improvementSection.addRow(row => {
row.addSuggestionChips('issueAreas', {
label: 'What went wrong? (Select all that apply)',
suggestions: [
{ id: 'slow', name: 'Too slow to resolve' },
{ id: 'unfair', name: 'Unfair resolution' },
{ id: 'rude', name: 'Staff was rude/unhelpful' },
{ id: 'communication', name: 'Poor communication' },
{ id: 'passed', name: 'Passed around too much' },
{ id: 'incomplete', name: 'Issue not fully resolved' },
{ id: 'effort', name: 'Required too much effort' },
{ id: 'promised', name: 'Promises not kept' }
],
alignment: 'left'
});
});
improvementSection.addSpacer();
improvementSection.addRow(row => {
row.addTextarea('improvementSuggestion', {
label: 'What would have made this experience better?',
placeholder: 'Please share specific suggestions for improvement...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 7: Additional Feedback
// ============================================
const feedbackSection = form.addSubform('feedback', {
title: 'Additional Comments',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
feedbackSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Is there anything else you\'d like to share about your experience?',
placeholder: 'Any additional feedback is appreciated...',
rows: 3,
autoExpand: true
});
});
feedbackSection.addRow(row => {
row.addCheckbox('contactPermission', {
label: 'You may contact me for follow-up regarding this feedback'
});
});
feedbackSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Email address',
placeholder: 'your@email.com',
isVisible: () => feedbackSection.checkbox('contactPermission')?.value() === true,
isRequired: () => feedbackSection.checkbox('contactPermission')?.value() === true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
const fairness = resolutionSection.thumbRating('fairnessRating')?.value();
const effort = resolutionSection.ratingScale('effortScore')?.value();
const trust = trustSection.ratingScale('trustRestored')?.value();
const futureIntent = trustSection.radioButton('futureIntent')?.value();
const issues = improvementSection.suggestionChips('issueAreas')?.value() || [];
if (!feeling) return '';
const feelingLabels: Record<string, string> = {
'very-bad': '😢 Very Dissatisfied',
'bad': '😕 Dissatisfied',
'neutral': '😐 Neutral',
'good': '🙂 Satisfied',
'excellent': '😃 Very Satisfied'
};
let emoji = '📋';
if (feeling === 'excellent' || feeling === 'good') emoji = '✅';
else if (feeling === 'neutral') emoji = '⚠️';
else emoji = '❌';
let summary = `${emoji} Resolution Feedback Summary\n`;
summary += `${'═'.repeat(32)}\n\n`;
summary += `Overall Feeling: ${feelingLabels[feeling] || feeling}\n`;
if (fairness) {
summary += `Fairness: ${fairness === 'up' ? '👍 Fair' : '👎 Unfair'}\n`;
}
if (effort) {
const effortLabel = effort >= 5 ? 'Easy' : effort >= 3 ? 'Moderate' : 'Difficult';
summary += `Effort Score: ${effort}/7 (${effortLabel})\n`;
}
if (trust) {
const trustLabel = trust >= 4 ? 'Restored' : trust >= 3 ? 'Partially' : 'Not restored';
summary += `Trust: ${trustLabel}\n`;
}
if (futureIntent) {
const intentLabels: Record<string, string> = {
'definitely': 'Will definitely continue',
'probably': 'Will probably continue',
'unsure': 'Unsure',
'probablyNot': 'Probably won\'t continue',
'definitelyNot': 'Won\'t continue'
};
summary += `Future Intent: ${intentLabels[futureIntent] || futureIntent}\n`;
}
if (issues.length > 0) {
summary += `\n⚠️ Issues identified: ${issues.length}`;
}
return summary;
},
customStyles: () => {
const feeling = overallSection.emojiRating('overallFeeling')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (feeling === 'excellent' || feeling === 'good') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (feeling === 'neutral') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => overallSection.emojiRating('overallFeeling')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback',
message: 'Your input helps us improve our complaint handling process. We take every piece of feedback seriously and use it to serve you better in the future.'
});
}