export function farmersMarketCustomerSurvey(form: FormTs) {
// Farmers Market Customer Survey
// Demonstrates: StarRating, EmojiRating, MatrixQuestion, RatingScale, CheckboxList, Slider, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Farmers Market Customer Survey',
computedValue: () => 'Help us make your market experience even better!',
customStyles: {
background: 'linear-gradient(135deg, #65a30d 0%, #84cc16 100%)',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Visit Information
// ============================================
const visitSection = form.addSubform('visitSection', {
title: 'About Your Visit'
});
visitSection.addRow(row => {
row.addRadioButton('visitFrequency', {
label: 'How often do you visit this farmers market?',
orientation: 'vertical',
isRequired: true,
options: [
{ id: 'first-time', name: 'This is my first visit' },
{ id: 'occasionally', name: 'Occasionally (a few times a year)' },
{ id: 'monthly', name: 'Monthly' },
{ id: 'bi-weekly', name: 'Every two weeks' },
{ id: 'weekly', name: 'Every week' }
]
});
});
visitSection.addRow(row => {
row.addRadioButton('purchasedToday', {
label: 'Did you make any purchases today?',
orientation: 'horizontal',
isRequired: true,
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No, just browsing' }
]
});
});
visitSection.addRow(row => {
row.addCheckboxList('purchaseCategories', {
label: 'What did you purchase? (Select all that apply)',
orientation: 'vertical',
isVisible: () => visitSection.radioButton('purchasedToday')?.value() === 'yes',
options: [
{ id: 'vegetables', name: 'Fresh vegetables' },
{ id: 'fruits', name: 'Fruits & berries' },
{ id: 'herbs', name: 'Herbs & spices' },
{ id: 'meat', name: 'Meat & poultry' },
{ id: 'eggs', name: 'Eggs' },
{ id: 'dairy', name: 'Dairy products' },
{ id: 'baked', name: 'Baked goods' },
{ id: 'honey', name: 'Honey & preserves' },
{ id: 'flowers', name: 'Flowers & plants' },
{ id: 'crafts', name: 'Handmade crafts' },
{ id: 'prepared', name: 'Prepared foods' }
]
});
});
visitSection.addRow(row => {
row.addSlider('spendingAmount', {
label: 'Approximately how much did you spend today?',
min: 0,
max: 200,
step: 10,
unit: '$',
showValue: true,
defaultValue: 50,
isVisible: () => visitSection.radioButton('purchasedToday')?.value() === 'yes'
});
});
// ============================================
// SECTION 2: Product Quality
// ============================================
const qualitySection = form.addSubform('qualitySection', {
title: 'Product Quality & Selection',
isVisible: () => visitSection.radioButton('purchasedToday')?.value() === 'yes'
});
qualitySection.addRow(row => {
row.addMatrixQuestion('productRatings', {
label: 'How would you rate the following?',
rows: [
{ id: 'freshness', label: 'Product freshness', isRequired: true },
{ id: 'variety', label: 'Product variety', isRequired: true },
{ id: 'quality', label: 'Overall quality', isRequired: true },
{ id: 'organic', label: 'Organic/local options', isRequired: false },
{ id: 'seasonal', label: 'Seasonal offerings', isRequired: false }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
qualitySection.addRow(row => {
row.addStarRating('overallProductQuality', {
label: 'Overall product quality rating',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
// ============================================
// SECTION 3: Pricing
// ============================================
const pricingSection = form.addSubform('pricingSection', {
title: 'Pricing',
isVisible: () => visitSection.radioButton('purchasedToday')?.value() === 'yes'
});
pricingSection.addRow(row => {
row.addRatingScale('valuePerception', {
label: 'How do you feel about the prices at this market?',
preset: 'custom',
min: 1,
max: 5,
lowLabel: 'Too expensive',
highLabel: 'Great value',
alignment: 'center',
variant: 'segmented'
});
});
pricingSection.addRow(row => {
row.addRadioButton('priceComparison', {
label: 'Compared to grocery store prices, the market is:',
orientation: 'horizontal',
options: [
{ id: 'much-more', name: 'Much more expensive' },
{ id: 'slightly-more', name: 'Slightly more' },
{ id: 'about-same', name: 'About the same' },
{ id: 'slightly-less', name: 'Slightly less' },
{ id: 'much-less', name: 'Much less expensive' }
]
});
});
pricingSection.addRow(row => {
row.addCheckbox('worthPremium', {
label: 'I believe the quality justifies any premium pricing',
isVisible: () => {
const comparison = pricingSection.radioButton('priceComparison')?.value();
return comparison === 'much-more' || comparison === 'slightly-more';
}
});
});
// ============================================
// SECTION 4: Vendor Experience
// ============================================
const vendorSection = form.addSubform('vendorSection', {
title: 'Vendor Experience'
});
vendorSection.addRow(row => {
row.addMatrixQuestion('vendorRatings', {
label: 'Rate your experience with market vendors',
rows: [
{ id: 'friendliness', label: 'Friendliness & helpfulness', isRequired: true },
{ id: 'knowledge', label: 'Product knowledge', isRequired: true },
{ id: 'samples', label: 'Availability of samples', isRequired: false },
{ id: 'payment', label: 'Payment options', isRequired: false }
],
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
});
});
vendorSection.addRow(row => {
row.addTextbox('favoriteVendor', {
label: 'Do you have a favorite vendor? (Optional)',
placeholder: 'Vendor name or product type...'
});
});
// ============================================
// SECTION 5: Market Atmosphere
// ============================================
const atmosphereSection = form.addSubform('atmosphereSection', {
title: 'Market Atmosphere & Facilities'
});
atmosphereSection.addRow(row => {
row.addEmojiRating('atmosphereRating', {
label: 'How would you describe the market atmosphere?',
preset: 'satisfaction',
size: 'lg',
alignment: 'center',
showLabels: true
});
});
atmosphereSection.addRow(row => {
row.addStarRating('cleanliness', {
label: 'Cleanliness',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('accessibility', {
label: 'Accessibility',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
atmosphereSection.addRow(row => {
row.addStarRating('parking', {
label: 'Parking availability',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('layout', {
label: 'Market layout',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
atmosphereSection.addRow(row => {
row.addCheckboxList('wouldLike', {
label: 'What would you like to see more of?',
orientation: 'vertical',
options: [
{ id: 'seating', name: 'More seating areas' },
{ id: 'shade', name: 'More shade/weather protection' },
{ id: 'music', name: 'Live music/entertainment' },
{ id: 'kids', name: 'Activities for children' },
{ id: 'cooking', name: 'Cooking demonstrations' },
{ id: 'education', name: 'Farm/garden education' },
{ id: 'restrooms', name: 'Better restroom facilities' },
{ id: 'atm', name: 'ATM/cash machine' }
]
});
});
// ============================================
// SECTION 6: Overall Satisfaction
// ============================================
const satisfactionSection = form.addSubform('satisfactionSection', {
title: 'Overall Satisfaction',
customStyles: () => {
const npsCategory = satisfactionSection.ratingScale('recommendScore')?.npsCategory();
if (npsCategory === 'promoter') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (npsCategory === 'passive') return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
if (npsCategory === 'detractor') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px' };
}
});
satisfactionSection.addRow(row => {
row.addRatingScale('recommendScore', {
label: 'How likely are you to recommend this market to friends or family?',
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true,
alignment: 'center'
});
});
satisfactionSection.addRow(row => {
row.addRadioButton('willReturn', {
label: 'Will you visit this market again?',
orientation: 'horizontal',
options: [
{ id: 'definitely', name: 'Definitely' },
{ id: 'probably', name: 'Probably' },
{ id: 'not-sure', name: 'Not sure' },
{ id: 'probably-not', name: 'Probably not' },
{ id: 'no', name: 'No' }
]
});
});
satisfactionSection.addRow(row => {
row.addTextarea('whyNotReturn', {
label: 'What would need to change for you to visit again?',
placeholder: 'Please share your concerns...',
rows: 2,
isVisible: () => {
const willReturn = satisfactionSection.radioButton('willReturn')?.value();
return willReturn === 'probably-not' || willReturn === 'no' || willReturn === 'not-sure';
}
});
});
// ============================================
// SECTION 7: Suggestions
// ============================================
const suggestionsSection = form.addSubform('suggestionsSection', {
title: 'Your Suggestions'
});
suggestionsSection.addRow(row => {
row.addSuggestionChips('improvementAreas', {
label: 'What areas could be improved? (Select up to 3)',
suggestions: [
{ id: 'variety', name: 'More variety' },
{ id: 'hours', name: 'Better hours' },
{ id: 'parking', name: 'More parking' },
{ id: 'prices', name: 'Lower prices' },
{ id: 'signage', name: 'Better signage' },
{ id: 'online', name: 'Online ordering' },
{ id: 'events', name: 'More events' },
{ id: 'none', name: 'Nothing - it\'s great!' }
],
max: 3,
alignment: 'center'
});
});
suggestionsSection.addSpacer();
suggestionsSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Any other comments or suggestions?',
placeholder: 'Share what you love about the market or ideas for improvement...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 8: Contact (Optional)
// ============================================
const contactSection = form.addSubform('contactSection', {
title: 'Stay Connected (Optional)'
});
contactSection.addRow(row => {
row.addCheckbox('joinNewsletter', {
label: 'Sign me up for the market newsletter'
});
});
contactSection.addRow(row => {
row.addEmail('email', {
label: 'Email address',
placeholder: 'your@email.com',
isVisible: () => contactSection.checkbox('joinNewsletter')?.value() === true,
isRequired: () => contactSection.checkbox('joinNewsletter')?.value() === true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => {
const nps = satisfactionSection.ratingScale('recommendScore')?.value();
return nps !== null && nps !== undefined;
}
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const frequency = visitSection.radioButton('visitFrequency')?.value();
const purchased = visitSection.radioButton('purchasedToday')?.value();
const spending = visitSection.slider('spendingAmount')?.value();
const productQuality = qualitySection.starRating('overallProductQuality')?.value();
const atmosphere = atmosphereSection.emojiRating('atmosphereRating')?.value();
const nps = satisfactionSection.ratingScale('recommendScore')?.value();
const npsCategory = satisfactionSection.ratingScale('recommendScore')?.npsCategory();
const improvements = suggestionsSection.suggestionChips('improvementAreas')?.value() || [];
const frequencyLabels: Record<string, string> = {
'first-time': 'First-time visitor',
'occasionally': 'Occasional visitor',
'monthly': 'Monthly visitor',
'bi-weekly': 'Bi-weekly visitor',
'weekly': 'Weekly regular'
};
let summary = `Farmers Market Survey\n`;
summary += `${'═'.repeat(25)}\n\n`;
summary += `Visitor Type: ${frequencyLabels[frequency || ''] || 'N/A'}\n`;
if (purchased === 'yes') {
summary += `Purchased: Yes ($${spending || 0})\n`;
if (productQuality) {
summary += `Product Quality: ${productQuality}/5 stars\n`;
}
} else {
summary += `Purchased: Just browsing\n`;
}
if (atmosphere) {
const atmosphereLabels: Record<string, string> = {
'very-bad': 'Poor',
'bad': 'Below Average',
'neutral': 'Average',
'good': 'Good',
'excellent': 'Excellent'
};
summary += `Atmosphere: ${atmosphereLabels[atmosphere] || atmosphere}\n`;
}
if (nps !== null && nps !== undefined) {
summary += `\nNPS: ${nps}/10 (${npsCategory})\n`;
}
if (improvements.length > 0 && !improvements.includes('none')) {
summary += `Improvement Areas: ${improvements.length} selected`;
}
return summary;
},
customStyles: () => {
const npsCategory = satisfactionSection.ratingScale('recommendScore')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (npsCategory === 'promoter') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #65a30d' };
} else if (npsCategory === 'detractor') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#fef9c3', borderLeft: '4px solid #ca8a04' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => visitSection.radioButton('visitFrequency')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your input helps us support local farmers and improve your market experience. We appreciate you taking the time to share your thoughts. See you at the market!'
});
}