export function csaMemberFeedback(form: FormTs) {
// CSA Member Feedback - Farm box subscription survey
// Demonstrates: StarRating, MatrixQuestion, SuggestionChips, Integer, Slider, Dropdown, EmojiRating, conditional sections
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Farm Box Feedback',
computedValue: () => 'Your feedback helps us grow better food for your table.',
customStyles: {
backgroundColor: '#15803d',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Box Information
// ============================================
const boxInfoSection = form.addSubform('boxInfoSection', {
title: 'This Week\'s Box',
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #bbf7d0' }
});
boxInfoSection.addRow(row => {
row.addDatepicker('boxDate', {
label: 'Box pickup/delivery date',
maxDate: () => new Date().toISOString(),
isRequired: true
}, '1fr');
row.addDropdown('boxSize', {
label: 'Your share size',
options: [
{ id: 'small', name: 'Small share' },
{ id: 'medium', name: 'Medium share' },
{ id: 'large', name: 'Large/Family share' },
{ id: 'half', name: 'Half share (bi-weekly)' }
],
placeholder: 'Select share size'
}, '1fr');
});
boxInfoSection.addRow(row => {
row.addDropdown('pickupMethod', {
label: 'How did you receive your box?',
options: [
{ id: 'farm-pickup', name: 'Farm pickup' },
{ id: 'market-pickup', name: 'Farmers market pickup' },
{ id: 'delivery-site', name: 'Delivery site pickup' },
{ id: 'home-delivery', name: 'Home delivery' }
],
placeholder: 'Select pickup method'
});
});
// ============================================
// SECTION 2: Overall Box Rating
// ============================================
const overallSection = form.addSubform('overallSection', {
title: 'Overall Satisfaction',
customStyles: () => {
const rating = overallSection.starRating('overallRating')?.value();
if (rating !== null && rating !== undefined) {
if (rating >= 4) return { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #15803d' };
if (rating >= 3) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #f59e0b' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #ef4444' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #86efac' };
}
});
overallSection.addRow(row => {
row.addStarRating('overallRating', {
label: 'How would you rate this week\'s box overall?',
maxStars: 5,
size: 'xl',
alignment: 'center',
filledColor: '#15803d',
showConfettiOnMax: true
});
});
overallSection.addRow(row => {
row.addEmojiRating('boxMood', {
label: 'How did you feel when you opened your box?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 3: Produce Quality Matrix
// ============================================
const qualitySection = form.addSubform('qualitySection', {
title: 'Produce Quality',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null,
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #bbf7d0' }
});
qualitySection.addRow(row => {
row.addMatrixQuestion('produceQuality', {
label: 'Rate the quality of produce categories in your box:',
rows: [
{ id: 'leafy', label: 'Leafy Greens', description: 'Lettuce, spinach, kale, etc.', isRequired: false },
{ id: 'root', label: 'Root Vegetables', description: 'Carrots, beets, potatoes, etc.', isRequired: false },
{ id: 'fruit', label: 'Fruits', description: 'Tomatoes, berries, melons, etc.', isRequired: false },
{ id: 'herbs', label: 'Herbs', description: 'Basil, cilantro, parsley, etc.', isRequired: false },
{ id: 'other', label: 'Other Items', description: 'Squash, peppers, etc.', isRequired: false }
],
columns: [
{ id: 'na', label: 'Not in box' },
{ 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
});
});
qualitySection.addRow(row => {
row.addStarRating('freshnessRating', {
label: 'Freshness of produce',
maxStars: 5,
size: 'lg',
alignment: 'center',
filledColor: '#15803d'
}, '1fr');
row.addStarRating('varietyRating', {
label: 'Variety in this box',
maxStars: 5,
size: 'lg',
alignment: 'center',
filledColor: '#15803d'
}, '1fr');
});
// ============================================
// SECTION 4: Quantity & Value
// ============================================
const quantitySection = form.addSubform('quantitySection', {
title: 'Quantity & Value',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
quantitySection.addRow(row => {
row.addRadioButton('quantityFeeling', {
label: 'How do you feel about the amount of produce?',
options: [
{ id: 'too-little', name: 'Not enough - I wanted more' },
{ id: 'just-right', name: 'Just right - perfect amount' },
{ id: 'too-much', name: 'Too much - some went to waste' }
],
orientation: 'vertical'
});
});
// Conditional: Too much waste
const wasteSection = quantitySection.addSubform('wasteSection', {
isVisible: () => quantitySection.radioButton('quantityFeeling')?.value() === 'too-much',
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', marginTop: '12px' }
});
wasteSection.addRow(row => {
row.addSlider('wastePercent', {
label: 'Approximately what percent went unused?',
min: 0,
max: 50,
step: 5,
showValue: true,
unit: '%',
defaultValue: 10
});
});
wasteSection.addRow(row => {
row.addSuggestionChips('wasteReasons', {
label: 'Why did produce go unused?',
suggestions: [
{ id: 'unfamiliar', name: 'Unfamiliar item' },
{ id: 'no-time', name: 'No time to cook' },
{ id: 'too-much', name: 'Quantity too large' },
{ id: 'spoiled', name: 'Spoiled too quickly' },
{ id: 'dislike', name: 'Don\'t like the item' },
{ id: 'forgot', name: 'Forgot about it' }
],
alignment: 'center'
});
});
quantitySection.addRow(row => {
row.addRatingScale('valueRating', {
preset: 'likert-5',
label: 'This box was good value for the price',
lowLabel: 'Strongly Disagree',
highLabel: 'Strongly Agree',
alignment: 'center'
});
});
// ============================================
// SECTION 5: Favorites & Requests
// ============================================
const preferencesSection = form.addSubform('preferencesSection', {
title: 'Favorites & Preferences',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null,
customStyles: { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' }
});
preferencesSection.addRow(row => {
row.addSuggestionChips('favorites', {
label: 'What were your favorite items this week? (select up to 3)',
suggestions: [
{ id: 'tomatoes', name: 'Tomatoes' },
{ id: 'greens', name: 'Salad greens' },
{ id: 'carrots', name: 'Carrots' },
{ id: 'peppers', name: 'Peppers' },
{ id: 'squash', name: 'Squash' },
{ id: 'herbs', name: 'Fresh herbs' },
{ id: 'berries', name: 'Berries' },
{ id: 'onions', name: 'Onions/Garlic' },
{ id: 'potatoes', name: 'Potatoes' },
{ id: 'beans', name: 'Green beans' }
],
max: 3,
alignment: 'center'
});
});
preferencesSection.addRow(row => {
row.addSuggestionChips('wantMore', {
label: 'What would you like to see more of?',
suggestions: [
{ id: 'tomatoes', name: 'Tomatoes' },
{ id: 'greens', name: 'Salad greens' },
{ id: 'fruit', name: 'Fresh fruit' },
{ id: 'herbs', name: 'Cooking herbs' },
{ id: 'roots', name: 'Root vegetables' },
{ id: 'specialty', name: 'Specialty items' },
{ id: 'cooking', name: 'Cooking vegetables' },
{ id: 'snacking', name: 'Snacking items' }
],
max: 3,
alignment: 'center'
});
});
preferencesSection.addRow(row => {
row.addTextarea('specificRequests', {
label: 'Any specific items you\'d love to see in future boxes?',
placeholder: 'e.g., more heirloom tomatoes, fresh basil, cherry tomatoes...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 6: Recipe & Storage Info
// ============================================
const supportSection = form.addSubform('supportSection', {
title: 'Recipes & Information',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
supportSection.addRow(row => {
row.addRadioButton('usedRecipes', {
label: 'Did you use any of the recipe suggestions we provided?',
options: [
{ id: 'yes', name: 'Yes, they were helpful' },
{ id: 'some', name: 'I read them but cooked my own way' },
{ id: 'no', name: 'No, I didn\'t look at them' },
{ id: 'na', name: 'I didn\'t receive recipes' }
],
orientation: 'vertical'
});
});
supportSection.addRow(row => {
row.addThumbRating('wantRecipes', {
label: 'Would you like more recipe ideas?',
showLabels: true,
upLabel: 'Yes please!',
downLabel: 'No thanks',
alignment: 'center',
size: 'lg'
}, '1fr');
row.addThumbRating('wantStorage', {
label: 'Would storage tips be helpful?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No need',
alignment: 'center',
size: 'lg'
}, '1fr');
});
// ============================================
// SECTION 7: Additional Comments
// ============================================
const commentsSection = form.addSubform('commentsSection', {
title: 'Additional Feedback',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
commentsSection.addSpacer();
commentsSection.addRow(row => {
row.addTextarea('comments', {
label: () => {
const rating = overallSection.starRating('overallRating')?.value();
if (rating !== null && rating !== undefined && rating >= 4) {
return 'What made this week\'s box great?';
}
return 'How can we improve your farm box experience?';
},
placeholder: 'Share your thoughts with us...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const overall = overallSection.starRating('overallRating')?.value();
const mood = overallSection.emojiRating('boxMood')?.value();
const freshness = qualitySection.starRating('freshnessRating')?.value();
const variety = qualitySection.starRating('varietyRating')?.value();
const quantity = quantitySection.radioButton('quantityFeeling')?.value();
const favorites = preferencesSection.suggestionChips('favorites')?.value() || [];
const wantMore = preferencesSection.suggestionChips('wantMore')?.value() || [];
if (overall === null || overall === undefined) return '';
const moodLabels: Record<string, string> = {
'very-bad': 'Disappointed',
'bad': 'Underwhelmed',
'neutral': 'Neutral',
'good': 'Happy',
'excellent': 'Delighted'
};
const quantityLabels: Record<string, string> = {
'too-little': 'Wanted more',
'just-right': 'Just right',
'too-much': 'Too much'
};
let emoji = '';
if (overall >= 4) emoji = '🥬';
else if (overall >= 3) emoji = '🌱';
else emoji = '📝';
let summary = `${emoji} FARM BOX FEEDBACK\n`;
summary += `${'═'.repeat(25)}\n\n`;
summary += `Overall: ${'★'.repeat(overall)}${'☆'.repeat(5 - overall)} (${overall}/5)\n`;
if (mood) {
summary += `Feeling: ${moodLabels[mood] || mood}\n`;
}
if (freshness) {
summary += `\nFreshness: ${'★'.repeat(freshness)}${'☆'.repeat(5 - freshness)}\n`;
}
if (variety) {
summary += `Variety: ${'★'.repeat(variety)}${'☆'.repeat(5 - variety)}\n`;
}
if (quantity) {
summary += `\nQuantity: ${quantityLabels[quantity]}`;
}
if (favorites.length > 0) {
summary += `\n\n🌟 Favorites: ${favorites.length} items`;
}
if (wantMore.length > 0) {
summary += `\n📋 Want more: ${wantMore.length} requests`;
}
return summary;
},
customStyles: () => {
const overall = overallSection.starRating('overallRating')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (overall !== null && overall !== undefined) {
if (overall >= 4) {
return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #15803d' };
} else if (overall >= 3) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #15803d' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => overallSection.starRating('overallRating')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your input helps us grow the best produce for your table. We read every response and use your feedback to improve our farm shares. Happy cooking!'
});
}