export function returnsExperienceSurvey(form: FormTs) {
// Returns Experience Survey - Comprehensive return process feedback
// Demonstrates: CES Scale, StarRating, MatrixQuestion, Slider, Conditional Flows
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'How Was Your Return Experience?',
computedValue: () => 'Help us improve our returns process with your feedback.',
customStyles: {
background: 'linear-gradient(135deg, #7c3aed 0%, #5b21b6 100%)',
color: 'white',
padding: '28px',
borderRadius: '12px',
textAlign: 'center',
fontSize: '15px'
}
});
});
// ============================================
// SECTION 1: Customer Effort Score
// ============================================
const effortSection = form.addSubform('effort', {
title: 'Overall Effort',
customStyles: () => {
const ces = effortSection.ratingScale('effortScore')?.value();
if (ces !== null && ces !== undefined) {
if (ces >= 6) return { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' };
if (ces >= 4) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
effortSection.addRow(row => {
row.addRatingScale('effortScore', {
preset: 'ces',
label: 'How easy was it to return your product?',
size: 'lg',
alignment: 'center',
isRequired: true
});
});
// ============================================
// SECTION 2: Return Reason
// ============================================
const reasonSection = form.addSubform('reason', {
title: 'Return Details',
isVisible: () => effortSection.ratingScale('effortScore')?.value() !== null
});
reasonSection.addRow(row => {
row.addRadioButton('returnReason', {
label: 'Why did you return this product?',
options: [
{ id: 'wrong-size', name: 'Wrong size/fit' },
{ id: 'not-as-described', name: 'Product not as described' },
{ id: 'quality-issue', name: 'Quality issues/defective' },
{ id: 'changed-mind', name: 'Changed my mind' },
{ id: 'found-better', name: 'Found a better alternative' },
{ id: 'arrived-late', name: 'Arrived too late' },
{ id: 'damaged', name: 'Arrived damaged' },
{ id: 'other', name: 'Other reason' }
],
orientation: 'vertical',
isRequired: true
});
});
reasonSection.addRow(row => {
row.addTextbox('otherReason', {
label: 'Please specify:',
placeholder: 'Describe your return reason...',
isVisible: () => reasonSection.radioButton('returnReason')?.value() === 'other',
isRequired: () => reasonSection.radioButton('returnReason')?.value() === 'other'
});
});
// ============================================
// SECTION 3: Process Touchpoints (Matrix)
// ============================================
const touchpointsSection = form.addSubform('touchpoints', {
title: 'Rate Each Step',
isVisible: () => reasonSection.radioButton('returnReason')?.value() !== null,
customStyles: { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' }
});
touchpointsSection.addRow(row => {
row.addMatrixQuestion('processRatings', {
label: 'How would you rate each step of the return process?',
rows: [
{ id: 'initiate', label: 'Initiating the return request', isRequired: true },
{ id: 'label', label: 'Getting the return label', isRequired: true },
{ id: 'packaging', label: 'Packaging instructions', isRequired: false },
{ id: 'dropoff', label: 'Drop-off / Pickup experience', isRequired: true },
{ id: 'tracking', label: 'Return tracking updates', isRequired: false },
{ id: 'refund', label: 'Refund processing', isRequired: true }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' },
{ id: 'na', label: 'N/A' }
],
fullWidth: true,
striped: true
});
});
// ============================================
// SECTION 4: Return Method & Timing
// ============================================
const methodSection = form.addSubform('method', {
title: 'Return Method',
isVisible: () => touchpointsSection.matrixQuestion('processRatings')?.areAllRequiredRowsAnswered() === true
});
methodSection.addRow(row => {
row.addRadioButton('returnMethod', {
label: 'How did you return the product?',
options: [
{ id: 'mail', name: 'Mail (dropped at carrier)' },
{ id: 'pickup', name: 'Scheduled pickup' },
{ id: 'store', name: 'In-store return' },
{ id: 'locker', name: 'Drop-off locker' }
],
orientation: 'horizontal'
});
});
methodSection.addRow(row => {
row.addSlider('refundDays', {
label: 'How many days did it take to receive your refund?',
min: 1,
max: 30,
step: 1,
showValue: true,
unit: 'days',
defaultValue: 7
});
});
methodSection.addRow(row => {
row.addStarRating('refundSpeedSatisfaction', {
label: 'How satisfied were you with the refund speed?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
// ============================================
// SECTION 5: Communication Quality
// ============================================
const communicationSection = form.addSubform('communication', {
title: 'Communication',
isVisible: () => methodSection.radioButton('returnMethod')?.value() !== null,
customStyles: { backgroundColor: '#eff6ff', padding: '16px', borderRadius: '8px' }
});
communicationSection.addRow(row => {
row.addStarRating('emailUpdates', {
label: 'Quality of email updates during the return',
maxStars: 5,
size: 'md'
}, '1fr');
row.addStarRating('statusClarity', {
label: 'Clarity of return status information',
maxStars: 5,
size: 'md'
}, '1fr');
});
communicationSection.addRow(row => {
row.addThumbRating('policyClarity', {
label: 'Was the return policy clear and easy to understand?',
size: 'lg',
showLabels: true,
upLabel: 'Yes, very clear',
downLabel: 'No, confusing',
alignment: 'center'
});
});
// ============================================
// SECTION 6: Pain Points (Conditional)
// ============================================
const painPointsSection = form.addSubform('painPoints', {
title: 'What Could Be Improved?',
isVisible: () => {
const ces = effortSection.ratingScale('effortScore')?.value();
return ces !== null && ces !== undefined && ces <= 4;
},
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
painPointsSection.addRow(row => {
row.addCheckboxList('painPointAreas', {
label: 'Which areas caused friction? (Select all that apply)',
options: [
{ id: 'find-return', name: 'Finding how to start a return' },
{ id: 'too-many-steps', name: 'Too many steps required' },
{ id: 'label-issues', name: 'Problems with return label' },
{ id: 'packaging-unclear', name: 'Unclear packaging requirements' },
{ id: 'dropoff-inconvenient', name: 'Inconvenient drop-off options' },
{ id: 'slow-refund', name: 'Slow refund processing' },
{ id: 'poor-communication', name: 'Poor communication/updates' },
{ id: 'support-needed', name: 'Needed to contact support' }
],
orientation: 'vertical'
});
});
painPointsSection.addSpacer({ height: '16px' });
painPointsSection.addRow(row => {
row.addTextarea('painPointDetails', {
label: 'Please describe what made the process difficult:',
placeholder: 'Share the specific issues you encountered...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 7: Future Behavior
// ============================================
const futureSection = form.addSubform('future', {
title: 'Looking Ahead',
isVisible: () => {
const method = methodSection.radioButton('returnMethod')?.value();
const ces = effortSection.ratingScale('effortScore')?.value();
return method !== null || (ces !== null && ces !== undefined && ces <= 4);
}
});
futureSection.addRow(row => {
row.addRadioButton('futureConfidence', {
label: 'Based on this experience, how confident are you in shopping with us again?',
options: [
{ id: 'very-confident', name: 'Very confident - easy returns give me peace of mind' },
{ id: 'somewhat-confident', name: 'Somewhat confident' },
{ id: 'neutral', name: 'Neutral - return experience was okay' },
{ id: 'less-confident', name: 'Less confident - might hesitate to order' },
{ id: 'not-confident', name: 'Not confident - return was too difficult' }
],
orientation: 'vertical'
});
});
futureSection.addRow(row => {
row.addSuggestionChips('improvements', {
label: 'What would improve our return process? (Select up to 3)',
suggestions: [
{ id: 'free-returns', name: 'Free return shipping' },
{ id: 'longer-window', name: 'Longer return window' },
{ id: 'instant-refund', name: 'Instant refunds' },
{ id: 'more-locations', name: 'More drop-off locations' },
{ id: 'home-pickup', name: 'Free home pickup' },
{ id: 'no-box', name: 'Boxless returns' },
{ id: 'exchange-option', name: 'Easy exchange option' },
{ id: 'better-tracking', name: 'Better tracking' }
],
max: 3,
alignment: 'center'
});
});
// ============================================
// SECTION 8: Additional Comments
// ============================================
const commentsSection = form.addSubform('comments', {
title: 'Additional Feedback',
isVisible: () => futureSection.radioButton('futureConfidence')?.value() !== null
});
commentsSection.addSpacer({ height: '8px' });
commentsSection.addRow(row => {
row.addTextarea('additionalFeedback', {
label: 'Any other comments about your return experience?',
placeholder: 'Share anything else you would like us to know...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Your Feedback Summary',
isVisible: () => futureSection.radioButton('futureConfidence')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const ces = effortSection.ratingScale('effortScore')?.value();
const reason = reasonSection.radioButton('returnReason')?.value();
const method = methodSection.radioButton('returnMethod')?.value();
const refundDays = methodSection.slider('refundDays')?.value();
const refundSatisfaction = methodSection.starRating('refundSpeedSatisfaction')?.value();
const confidence = futureSection.radioButton('futureConfidence')?.value();
const improvements = futureSection.suggestionChips('improvements')?.value() || [];
if (!ces) return '';
const cesLevel = ces >= 6 ? 'Easy' : ces >= 4 ? 'Moderate' : 'Difficult';
const cesEmoji = ces >= 6 ? '🟢' : ces >= 4 ? '🟡' : '🔴';
const reasonLabels: Record<string, string> = {
'wrong-size': 'Wrong size/fit',
'not-as-described': 'Not as described',
'quality-issue': 'Quality issue',
'changed-mind': 'Changed mind',
'found-better': 'Found better',
'arrived-late': 'Arrived late',
'damaged': 'Arrived damaged',
'other': 'Other'
};
const methodLabels: Record<string, string> = {
'mail': 'Mail drop-off',
'pickup': 'Scheduled pickup',
'store': 'In-store',
'locker': 'Drop-off locker'
};
let summary = 'Return Experience Summary\n';
summary += '═'.repeat(28) + '\n\n';
summary += `${cesEmoji} Effort Score: ${ces}/7 (${cesLevel})\n`;
summary += `Return Reason: ${reasonLabels[reason || ''] || 'Not specified'}\n`;
summary += `Return Method: ${methodLabels[method || ''] || 'Not specified'}\n`;
if (refundDays) {
summary += `Refund Time: ${refundDays} days\n`;
}
if (refundSatisfaction) {
summary += `Speed Satisfaction: ${'★'.repeat(refundSatisfaction)}${'☆'.repeat(5 - refundSatisfaction)}\n`;
}
if (improvements.length > 0) {
summary += `\nSuggested Improvements: ${improvements.length}`;
}
return summary;
},
customStyles: () => {
const ces = effortSection.ratingScale('effortScore')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (ces !== null && ces !== undefined) {
if (ces >= 6) return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #22c55e' };
if (ces >= 4) return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return baseStyles;
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Return Feedback',
isVisible: () => futureSection.radioButton('futureConfidence')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your input helps us improve our return process. We appreciate you taking the time to share your experience with us.'
});
}