export function loyaltyProgramFeedbackForm(form: FormTs) {
// Loyalty Program Feedback Survey
// Demonstrates: MatrixQuestion, StarRating, RatingScale (NPS), Slider, CheckboxList, EmojiRating, ThumbRating, SuggestionChips
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Share Your Loyalty Program Experience',
computedValue: () => 'Help us make our rewards program even better for you.',
customStyles: {
backgroundColor: '#7c3aed',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Membership Information
// ============================================
const membershipSection = form.addSubform('membershipInfo', {
title: 'Your Membership'
});
membershipSection.addRow(row => {
row.addDropdown('memberTier', {
label: 'Your current membership tier',
options: [
{ id: 'bronze', name: 'Bronze / Basic' },
{ id: 'silver', name: 'Silver / Plus' },
{ id: 'gold', name: 'Gold / Premium' },
{ id: 'platinum', name: 'Platinum / VIP' }
],
placeholder: 'Select your tier',
isRequired: true
}, '1fr');
row.addDropdown('memberDuration', {
label: 'How long have you been a member?',
options: [
{ id: 'less-3m', name: 'Less than 3 months' },
{ id: '3-6m', name: '3-6 months' },
{ id: '6-12m', name: '6-12 months' },
{ id: '1-2y', name: '1-2 years' },
{ id: '2y-plus', name: 'More than 2 years' }
],
placeholder: 'Select duration',
isRequired: true
}, '1fr');
});
membershipSection.addRow(row => {
row.addSlider('usageFrequency', {
label: 'How often do you engage with the loyalty program per month?',
min: 0,
max: 20,
step: 1,
defaultValue: 5,
unit: 'times',
showValue: true
});
});
// ============================================
// SECTION 2: Overall Program Rating
// ============================================
const overallSection = form.addSubform('overallRating', {
title: 'Overall Program Satisfaction',
customStyles: () => {
const rating = overallSection.starRating('programSatisfaction')?.value();
if (rating && rating >= 4) return { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' };
if (rating && rating <= 2) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px' };
}
});
overallSection.addRow(row => {
row.addStarRating('programSatisfaction', {
label: 'How satisfied are you with our loyalty program overall?',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
overallSection.addRow(row => {
row.addEmojiRating('valuePerception', {
label: 'How do you feel about the value you get from the program?',
preset: 'satisfaction',
size: 'lg',
alignment: 'center'
});
});
// ============================================
// SECTION 3: Program Aspects Matrix
// ============================================
const aspectsSection = form.addSubform('programAspects', {
title: 'Rate Program Features'
});
aspectsSection.addRow(row => {
row.addMatrixQuestion('featureRatings', {
label: 'How would you rate the following aspects of our loyalty program?',
rows: [
{ id: 'earning', label: 'Ease of earning points', isRequired: true },
{ id: 'redemption', label: 'Ease of redeeming rewards', isRequired: true },
{ id: 'variety', label: 'Variety of rewards available' },
{ id: 'value', label: 'Value of rewards for points spent', isRequired: true },
{ id: 'communication', label: 'Communication about points/offers' },
{ id: 'app', label: 'Mobile app/website experience' },
{ id: 'support', label: 'Customer support for program issues' }
],
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
});
});
// ============================================
// SECTION 4: Reward Preferences
// ============================================
const rewardsSection = form.addSubform('rewardPreferences', {
title: 'Reward Preferences'
});
rewardsSection.addRow(row => {
row.addCheckboxList('favoriteRewards', {
label: 'Which types of rewards do you value most? (Select up to 3)',
options: [
{ id: 'discounts', name: 'Discounts on purchases' },
{ id: 'free-products', name: 'Free products' },
{ id: 'cashback', name: 'Cashback / statement credits' },
{ id: 'exclusive-access', name: 'Exclusive access to sales/products' },
{ id: 'experiences', name: 'Experiences (events, travel)' },
{ id: 'gift-cards', name: 'Gift cards' },
{ id: 'charity', name: 'Charitable donations' },
{ id: 'upgrades', name: 'Service upgrades' }
],
orientation: 'vertical',
max: 3
}, '1fr');
row.addCheckboxList('missingRewards', {
label: 'Which rewards would you like us to add?',
options: [
{ id: 'more-discounts', name: 'Deeper discounts' },
{ id: 'partner-rewards', name: 'Partner brand rewards' },
{ id: 'travel', name: 'Travel rewards' },
{ id: 'entertainment', name: 'Entertainment (movies, concerts)' },
{ id: 'wellness', name: 'Wellness & fitness' },
{ id: 'dining', name: 'Dining experiences' },
{ id: 'personalized', name: 'Personalized offers' },
{ id: 'instant', name: 'Instant rewards' }
],
orientation: 'vertical',
max: 3
}, '1fr');
});
// ============================================
// SECTION 5: Program Impact
// ============================================
const impactSection = form.addSubform('programImpact', {
title: 'Program Impact on Your Behavior'
});
impactSection.addRow(row => {
row.addThumbRating('influencesPurchase', {
label: 'Does the loyalty program influence where you shop?',
showLabels: true,
upLabel: 'Yes, it does',
downLabel: 'No, not really',
size: 'lg',
alignment: 'center'
});
});
impactSection.addRow(row => {
row.addRatingScale('spendMore', {
label: 'How much more likely are you to spend with us because of the program?',
preset: 'likert-5',
lowLabel: 'No more likely',
highLabel: 'Much more likely',
size: 'md',
alignment: 'center',
isVisible: () => impactSection.thumbRating('influencesPurchase')?.value() === 'up'
});
});
// ============================================
// SECTION 6: NPS for Program
// ============================================
const npsSection = form.addSubform('programNps', {
title: 'Would You Recommend?',
customStyles: () => {
const category = npsSection.ratingScale('programNps')?.npsCategory();
if (category === 'promoter') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (category === 'passive') return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
if (category === 'detractor') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px' };
}
});
npsSection.addRow(row => {
row.addRatingScale('programNps', {
label: 'How likely are you to recommend our loyalty program to friends?',
preset: 'nps',
showSegmentColors: true,
showCategoryLabel: true,
showConfettiOnPromoter: true,
isRequired: true
});
});
// ============================================
// SECTION 7: Improvements (for non-promoters)
// ============================================
const improvementSection = form.addSubform('improvements', {
title: 'Help Us Improve',
isVisible: () => {
const nps = npsSection.ratingScale('programNps')?.value();
return nps !== null && nps !== undefined && nps < 9;
}
});
improvementSection.addRow(row => {
row.addSuggestionChips('painPoints', {
label: () => {
const nps = npsSection.ratingScale('programNps')?.value();
if (nps !== null && nps !== undefined && nps <= 6) {
return 'What are the biggest issues with our program?';
}
return 'What would make you rate us higher?';
},
suggestions: [
{ id: 'hard-earn', name: 'Hard to earn points' },
{ id: 'low-value', name: 'Rewards not valuable enough' },
{ id: 'expiry', name: 'Points expire too quickly' },
{ id: 'complex', name: 'Too complicated' },
{ id: 'poor-app', name: 'Poor app/website' },
{ id: 'limited-rewards', name: 'Limited reward options' },
{ id: 'communication', name: 'Poor communication' },
{ id: 'support', name: 'Bad customer support' }
],
alignment: 'center'
});
});
improvementSection.addSpacer();
improvementSection.addRow(row => {
row.addTextarea('improvementSuggestions', {
label: 'What specific improvements would you suggest?',
placeholder: 'Share your ideas to make our program better...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 8: Promoter Testimonial
// ============================================
const testimonialSection = form.addSubform('testimonial', {
title: 'Share Your Experience',
isVisible: () => {
const nps = npsSection.ratingScale('programNps')?.value();
return nps !== null && nps !== undefined && nps >= 9;
},
customStyles: { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' }
});
testimonialSection.addRow(row => {
row.addTextarea('testimonialText', {
label: "We'd love to hear what you enjoy most about our program!",
placeholder: 'Share what makes our loyalty program great for you...',
rows: 3,
autoExpand: true
});
});
testimonialSection.addRow(row => {
row.addCheckbox('canUseTestimonial', {
label: 'You may use my feedback as a testimonial (anonymously)'
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Your Feedback Summary',
isVisible: () => npsSection.ratingScale('programNps')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const tier = membershipSection.dropdown('memberTier')?.value();
const satisfaction = overallSection.starRating('programSatisfaction')?.value();
const nps = npsSection.ratingScale('programNps')?.value();
const npsCategory = npsSection.ratingScale('programNps')?.npsCategory();
const favoriteRewards = rewardsSection.checkboxList('favoriteRewards')?.value() || [];
const influences = impactSection.thumbRating('influencesPurchase')?.value();
if (!nps) return '';
const tierLabels: Record<string, string> = {
'bronze': 'Bronze',
'silver': 'Silver',
'gold': 'Gold',
'platinum': 'Platinum'
};
let summary = `Loyalty Program Feedback Summary\n`;
summary += `${'═'.repeat(35)}\n\n`;
if (tier) {
summary += `Membership Tier: ${tierLabels[tier] || tier}\n`;
}
if (satisfaction) {
summary += `Overall Satisfaction: ${'★'.repeat(satisfaction)}${'☆'.repeat(5 - satisfaction)}\n`;
}
summary += `\nProgram NPS: ${nps}/10`;
if (npsCategory) {
const emoji = npsCategory === 'promoter' ? ' (Promoter)' : npsCategory === 'passive' ? ' (Passive)' : ' (Detractor)';
summary += emoji;
}
if (favoriteRewards.length > 0) {
summary += `\n\nFavorite Rewards: ${favoriteRewards.length} selected`;
}
if (influences) {
summary += `\n\nInfluences Shopping: ${influences === 'up' ? 'Yes' : 'No'}`;
}
return summary;
},
customStyles: () => {
const category = npsSection.ratingScale('programNps')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (category === 'promoter') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (category === 'passive') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else if (category === 'detractor') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f1f5f9' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => npsSection.ratingScale('programNps')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your input helps us create a better loyalty program. As a thank you, we\'ve added 50 bonus points to your account!'
});
}