export function downgradeSurvey(form: FormTs) {
// Downgrade Feedback Survey - Understanding why customers reduce their subscription
// Demonstrates: MatrixQuestion, RatingScale, EmojiRating, conditional visibility, dynamic styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'We Want to Understand',
computedValue: () => 'Your feedback helps us improve. Please share why you decided to change your plan.',
customStyles: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white',
padding: '28px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Current Plan Context
// ============================================
const contextSection = form.addSubform('context', {
title: 'Your Plan Change'
});
contextSection.addRow(row => {
row.addDropdown('previousPlan', {
label: 'Which plan are you downgrading from?',
placeholder: 'Select your previous plan',
options: [
{ id: 'enterprise', name: 'Enterprise' },
{ id: 'business', name: 'Business' },
{ id: 'professional', name: 'Professional' },
{ id: 'starter', name: 'Starter' }
],
isRequired: true
}, '1fr');
row.addDropdown('newPlan', {
label: 'Which plan are you moving to?',
placeholder: 'Select your new plan',
options: () => {
const prev = contextSection.dropdown('previousPlan')?.value();
const allPlans = [
{ id: 'business', name: 'Business' },
{ id: 'professional', name: 'Professional' },
{ id: 'starter', name: 'Starter' },
{ id: 'free', name: 'Free' }
];
return allPlans.filter(p => {
const order = ['enterprise', 'business', 'professional', 'starter', 'free'];
return order.indexOf(p.id) > order.indexOf(prev || '');
});
},
isRequired: true
}, '1fr');
});
contextSection.addRow(row => {
row.addTextbox('accountDuration', {
label: 'How long have you been using our product?',
placeholder: 'e.g., 6 months, 2 years',
isRequired: true
});
});
// ============================================
// SECTION 2: Primary Reason
// ============================================
const reasonSection = form.addSubform('reason', {
title: 'Primary Reason for Downgrade',
isVisible: () => !!contextSection.dropdown('newPlan')?.value()
});
reasonSection.addRow(row => {
row.addRadioButton('primaryReason', {
label: 'What is the main reason for your downgrade?',
options: [
{ id: 'pricing', name: 'Price is too high for my needs' },
{ id: 'features-unused', name: 'Not using premium features enough' },
{ id: 'features-missing', name: 'Missing features I need' },
{ id: 'budget', name: 'Budget constraints' },
{ id: 'business-change', name: 'Business needs changed' },
{ id: 'competition', name: 'Found alternative solution' },
{ id: 'support', name: 'Support quality issues' },
{ id: 'other', name: 'Other reason' }
],
isRequired: true
});
});
reasonSection.addRow(row => {
row.addTextarea('otherReason', {
label: 'Please describe your reason',
placeholder: 'Tell us more about why you are downgrading...',
rows: 3,
isVisible: () => reasonSection.radioButton('primaryReason')?.value() === 'other',
isRequired: () => reasonSection.radioButton('primaryReason')?.value() === 'other'
});
});
// ============================================
// SECTION 3: Pricing Deep Dive (conditional)
// ============================================
const pricingSection = form.addSubform('pricing', {
title: 'Pricing Feedback',
isVisible: () => {
const reason = reasonSection.radioButton('primaryReason')?.value();
return reason === 'pricing' || reason === 'budget';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
pricingSection.addRow(row => {
row.addRatingScale('priceValue', {
label: 'How would you rate the value for money of your previous plan?',
preset: 'satisfaction',
showSegmentColors: false,
alignment: 'center'
});
});
pricingSection.addRow(row => {
row.addSlider('priceReduction', {
label: 'What price reduction would have kept you on the higher plan?',
min: 0,
max: 50,
step: 5,
unit: '%',
defaultValue: 20
});
});
pricingSection.addRow(row => {
row.addCheckboxList('pricingOptions', {
label: 'Which pricing options would help?',
options: [
{ id: 'annual', name: 'Annual billing discount' },
{ id: 'custom', name: 'Custom plan with only features I need' },
{ id: 'usage', name: 'Usage-based pricing' },
{ id: 'seats', name: 'Pay per seat/user' },
{ id: 'nonprofit', name: 'Non-profit/startup discount' }
]
});
});
// ============================================
// SECTION 4: Feature Usage Assessment
// ============================================
const featureSection = form.addSubform('features', {
title: 'Feature Assessment',
isVisible: () => {
const reason = reasonSection.radioButton('primaryReason')?.value();
return reason === 'features-unused' || reason === 'features-missing';
},
customStyles: { backgroundColor: '#dbeafe', padding: '16px', borderRadius: '8px' }
});
featureSection.addRow(row => {
row.addMatrixQuestion('featureUsage', {
label: 'How often did you use these premium features?',
rows: [
{ id: 'analytics', label: 'Advanced Analytics', isRequired: true },
{ id: 'integrations', label: 'Custom Integrations', isRequired: true },
{ id: 'automation', label: 'Workflow Automation', isRequired: true },
{ id: 'support', label: 'Priority Support', isRequired: true },
{ id: 'storage', label: 'Extended Storage', isRequired: true }
],
columns: [
{ id: 'daily', label: 'Daily' },
{ id: 'weekly', label: 'Weekly' },
{ id: 'monthly', label: 'Monthly' },
{ id: 'rarely', label: 'Rarely' },
{ id: 'never', label: 'Never' }
],
fullWidth: true
});
});
featureSection.addSpacer();
featureSection.addRow(row => {
row.addTextarea('missingFeatures', {
label: 'What features were you hoping to find but didn\'t?',
placeholder: 'Describe any features that would have made the upgrade worthwhile...',
rows: 3,
isVisible: () => reasonSection.radioButton('primaryReason')?.value() === 'features-missing'
});
});
// ============================================
// SECTION 5: Competition Analysis
// ============================================
const competitionSection = form.addSubform('competition', {
title: 'Alternative Solutions',
isVisible: () => reasonSection.radioButton('primaryReason')?.value() === 'competition',
customStyles: { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' }
});
competitionSection.addRow(row => {
row.addTextbox('competitorName', {
label: 'Which alternative are you considering or using?',
placeholder: 'e.g., Competitor X'
});
});
competitionSection.addRow(row => {
row.addCheckboxList('competitorAdvantages', {
label: 'What advantages does the alternative offer?',
options: [
{ id: 'price', name: 'Better pricing' },
{ id: 'features', name: 'More features' },
{ id: 'ease', name: 'Easier to use' },
{ id: 'support', name: 'Better support' },
{ id: 'integration', name: 'Better integrations' },
{ id: 'performance', name: 'Better performance' }
]
});
});
// ============================================
// SECTION 6: Overall Satisfaction
// ============================================
const satisfactionSection = form.addSubform('satisfaction', {
title: 'Overall Experience',
isVisible: () => !!reasonSection.radioButton('primaryReason')?.value()
});
satisfactionSection.addRow(row => {
row.addEmojiRating('overallMood', {
label: 'How do you feel about this change?',
preset: 'mood',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
satisfactionSection.addRow(row => {
row.addMatrixQuestion('satisfactionAspects', {
label: 'Rate your satisfaction with these aspects:',
rows: [
{ id: 'product', label: 'Product Quality' },
{ id: 'support', label: 'Customer Support' },
{ id: 'onboarding', label: 'Onboarding Experience' },
{ id: 'updates', label: 'Product Updates' },
{ id: 'reliability', label: 'Reliability/Uptime' }
],
columns: [
{ id: '1', label: 'Poor' },
{ id: '2', label: 'Fair' },
{ id: '3', label: 'Good' },
{ id: '4', label: 'Very Good' },
{ id: '5', label: 'Excellent' }
],
fullWidth: true
});
});
// ============================================
// SECTION 7: Future Intent
// ============================================
const futureSection = form.addSubform('future', {
title: 'Looking Ahead',
isVisible: () => !!satisfactionSection.emojiRating('overallMood')?.value()
});
futureSection.addRow(row => {
row.addRatingScale('returnLikelihood', {
label: 'How likely are you to upgrade again in the future?',
preset: 'nps',
showSegmentColors: true,
showCategoryLabel: true,
lowLabel: 'Very unlikely',
highLabel: 'Very likely'
});
});
futureSection.addRow(row => {
row.addCheckboxList('returnTriggers', {
label: () => {
const likelihood = futureSection.ratingScale('returnLikelihood')?.value();
if (likelihood !== null && likelihood !== undefined && likelihood >= 7) {
return 'What would make you upgrade again?';
}
return 'What would need to change for you to consider upgrading?';
},
options: [
{ id: 'price-drop', name: 'Lower pricing' },
{ id: 'new-features', name: 'New features I need' },
{ id: 'budget', name: 'Increased budget' },
{ id: 'team-growth', name: 'Team/business growth' },
{ id: 'promo', name: 'Special promotion/discount' },
{ id: 'competitor-fail', name: 'Alternative solution didn\'t work out' }
],
isVisible: () => futureSection.ratingScale('returnLikelihood')?.value() !== null
});
});
futureSection.addSpacer();
futureSection.addRow(row => {
row.addTextarea('finalFeedback', {
label: 'Any additional feedback or suggestions for us?',
placeholder: 'We read every response and use your feedback to improve...',
rows: 3
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => !!reasonSection.radioButton('primaryReason')?.value()
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const prevPlan = contextSection.dropdown('previousPlan')?.value();
const newPlan = contextSection.dropdown('newPlan')?.value();
const reason = reasonSection.radioButton('primaryReason')?.value();
const mood = satisfactionSection.emojiRating('overallMood')?.value();
const returnLikelihood = futureSection.ratingScale('returnLikelihood')?.value();
if (!reason) return '';
const reasonLabels: Record<string, string> = {
'pricing': 'Pricing concerns',
'features-unused': 'Underutilized features',
'features-missing': 'Missing features',
'budget': 'Budget constraints',
'business-change': 'Business needs changed',
'competition': 'Alternative solution',
'support': 'Support issues',
'other': 'Other reason'
};
const moodLabels: Record<string, string> = {
'sad': 'Disappointed',
'down': 'Uncertain',
'neutral': 'Neutral',
'happy': 'Satisfied',
'excited': 'Positive'
};
let summary = 'Summary of Your Feedback\n';
summary += '═'.repeat(30) + '\n\n';
if (prevPlan && newPlan) {
summary += `Plan Change: ${prevPlan.charAt(0).toUpperCase() + prevPlan.slice(1)} → ${newPlan.charAt(0).toUpperCase() + newPlan.slice(1)}\n`;
}
summary += `Primary Reason: ${reasonLabels[reason] || reason}\n`;
if (mood) {
summary += `Current Mood: ${moodLabels[mood] || mood}\n`;
}
if (returnLikelihood !== null && returnLikelihood !== undefined) {
const category = returnLikelihood >= 9 ? 'Very Likely' :
returnLikelihood >= 7 ? 'Likely' :
returnLikelihood >= 5 ? 'Neutral' : 'Unlikely';
summary += `Return Likelihood: ${returnLikelihood}/10 (${category})\n`;
}
return summary;
},
customStyles: () => {
const returnLikelihood = futureSection.ratingScale('returnLikelihood')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (returnLikelihood !== null && returnLikelihood !== undefined) {
if (returnLikelihood >= 7) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (returnLikelihood >= 5) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
return { ...baseStyles, backgroundColor: '#f1f5f9', borderLeft: '4px solid #64748b' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => !!reasonSection.radioButton('primaryReason')?.value()
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'We appreciate you taking the time to share your thoughts. Your feedback helps us improve our product and pricing. If you ever want to upgrade again, we\'ll be here!'
});
}