export function sportsCampFeedbackSurvey(form: FormTs) {
// Sports Camp Feedback - Participant and parent evaluation
// Demonstrates: StarRating, EmojiRating, MatrixQuestion, Slider, SuggestionChips, RadioButton, CheckboxList, conditional visibility, dynamic labels, dynamic styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Sports Camp Feedback',
computedValue: () => 'Help us make our camp even better! Share your experience.',
customStyles: {
backgroundColor: '#ea580c',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Respondent Information
// ============================================
const respondentSection = form.addSubform('respondent', {
title: 'About the Camper'
});
respondentSection.addRow(row => {
row.addRadioButton('respondentType', {
label: 'Who is completing this form?',
options: [
{ id: 'parent', name: 'Parent/Guardian of camper' },
{ id: 'teen', name: 'Teen camper (13-17)' },
{ id: 'adult', name: 'Adult participant (18+)' }
],
orientation: 'vertical',
isRequired: true
});
});
respondentSection.addRow(row => {
row.addTextbox('camperName', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent' ? "Camper's first name" : 'Your first name';
},
placeholder: 'First name only...',
isRequired: true
}, '1fr');
row.addDropdown('ageGroup', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent' ? "Camper's age group" : 'Your age group';
},
options: () => {
const type = respondentSection.radioButton('respondentType')?.value();
if (type === 'adult') {
return [
{ id: '18-24', name: '18-24 years' },
{ id: '25-34', name: '25-34 years' },
{ id: '35-44', name: '35-44 years' },
{ id: '45-54', name: '45-54 years' },
{ id: '55+', name: '55+ years' }
];
}
return [
{ id: '5-7', name: '5-7 years' },
{ id: '8-10', name: '8-10 years' },
{ id: '11-13', name: '11-13 years' },
{ id: '14-17', name: '14-17 years' }
];
},
isRequired: true
}, '1fr');
});
respondentSection.addRow(row => {
row.addDropdown('campSession', {
label: 'Which camp session did you attend?',
options: [
{ id: 'week1', name: 'Week 1 - June' },
{ id: 'week2', name: 'Week 2 - June' },
{ id: 'week3', name: 'Week 3 - July' },
{ id: 'week4', name: 'Week 4 - July' },
{ id: 'week5', name: 'Week 5 - August' },
{ id: 'full', name: 'Full Summer Program' }
],
isRequired: true
}, '1fr');
row.addRadioButton('firstTime', {
label: 'Is this your first time at our camp?',
options: [
{ id: 'yes', name: 'Yes, first time' },
{ id: 'no', name: 'Returning camper' }
],
orientation: 'horizontal',
isRequired: true
}, '1fr');
});
// ============================================
// SECTION 2: Fun Factor (Key Metric!)
// ============================================
const funSection = form.addSubform('fun', {
title: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent' ? 'The Fun Factor' : 'How Much Fun Did You Have?';
},
customStyles: () => {
const fun = funSection.emojiRating('funRating')?.value();
if (fun === 'excellent' || fun === 'good') {
return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #e5e7eb' };
}
});
funSection.addRow(row => {
row.addEmojiRating('funRating', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'How much fun did your child have at camp?'
: 'How much fun did you have at camp?';
},
preset: 'mood',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
funSection.addRow(row => {
row.addSuggestionChips('favoriteActivities', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'What activities did your child enjoy most?'
: 'What activities did you enjoy most?';
},
suggestions: [
{ id: 'drills', name: 'Skill Drills' },
{ id: 'games', name: 'Games & Scrimmages' },
{ id: 'competitions', name: 'Competitions' },
{ id: 'team-building', name: 'Team Building' },
{ id: 'water-activities', name: 'Water Activities' },
{ id: 'special-events', name: 'Special Events' },
{ id: 'free-play', name: 'Free Play Time' },
{ id: 'awards', name: 'Awards & Recognition' }
],
alignment: 'center',
isVisible: () => funSection.emojiRating('funRating')?.value() !== null
});
});
// ============================================
// SECTION 3: Coaching Evaluation
// ============================================
const coachingSection = form.addSubform('coaching', {
title: 'Coaching & Instruction'
});
coachingSection.addRow(row => {
row.addMatrixQuestion('coachRatings', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'Rate the coaching staff on these areas:'
: 'Rate your coaches on these areas:';
},
rows: [
{ id: 'knowledge', label: 'Sport Knowledge', description: 'Understanding of the game', isRequired: true },
{ id: 'teaching', label: 'Teaching Ability', description: 'Clear explanations and demos', isRequired: true },
{ id: 'patience', label: 'Patience', description: 'Supportive and encouraging', isRequired: true },
{ id: 'engagement', label: 'Engagement', description: 'Kept campers interested', isRequired: true },
{ id: 'feedback', label: 'Feedback Quality', description: 'Helpful corrections and praise', isRequired: true },
{ id: 'fairness', label: 'Fairness', description: 'Equal attention to all campers', isRequired: true }
],
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
});
});
coachingSection.addRow(row => {
row.addStarRating('overallCoaching', {
label: 'Overall coaching quality',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
// ============================================
// SECTION 4: Skill Development
// ============================================
const skillsSection = form.addSubform('skills', {
title: 'Skill Development'
});
skillsSection.addRow(row => {
row.addSlider('skillImprovement', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'How much did your child improve their skills during camp?'
: 'How much did you improve your skills during camp?';
},
min: 0,
max: 100,
step: 10,
showValue: true,
unit: '%',
defaultValue: 50
});
});
skillsSection.addRow(row => {
row.addMatrixQuestion('skillAreas', {
label: 'Rate improvement in specific skill areas:',
rows: [
{ id: 'fundamentals', label: 'Basic Fundamentals', description: 'Core techniques' },
{ id: 'game-sense', label: 'Game Sense', description: 'Strategy and decision-making' },
{ id: 'fitness', label: 'Fitness & Conditioning', description: 'Endurance and strength' },
{ id: 'teamwork', label: 'Teamwork', description: 'Working with others' },
{ id: 'confidence', label: 'Confidence', description: 'Self-belief and attitude' }
],
columns: [
{ id: 'none', label: 'No Change' },
{ id: 'slight', label: 'Slight' },
{ id: 'moderate', label: 'Moderate' },
{ id: 'significant', label: 'Significant' },
{ id: 'major', label: 'Major' }
],
striped: true,
fullWidth: true,
isVisible: () => (skillsSection.slider('skillImprovement')?.value() ?? 0) > 0
});
});
// ============================================
// SECTION 5: Safety & Supervision
// ============================================
const safetySection = form.addSubform('safety', {
title: 'Safety & Supervision',
isVisible: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent' || type === 'teen';
}
});
safetySection.addRow(row => {
row.addStarRating('safetyRating', {
label: 'How safe did you feel the camp environment was?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
safetySection.addRow(row => {
row.addCheckboxList('safetyAspects', {
label: 'Which safety aspects were handled well?',
options: [
{ id: 'supervision', name: 'Adequate staff supervision' },
{ id: 'equipment', name: 'Safe equipment and facilities' },
{ id: 'hydration', name: 'Hydration and rest breaks' },
{ id: 'first-aid', name: 'First aid availability' },
{ id: 'weather', name: 'Weather awareness' },
{ id: 'communication', name: 'Parent communication' }
],
orientation: 'vertical',
isVisible: () => (safetySection.starRating('safetyRating')?.value() ?? 0) >= 3
});
});
safetySection.addSpacer();
safetySection.addRow(row => {
row.addTextarea('safetyConcerns', {
label: 'Did you observe any safety concerns? (Optional)',
placeholder: 'Please share any safety-related feedback...',
rows: 2,
autoExpand: true,
isVisible: () => (safetySection.starRating('safetyRating')?.value() ?? 5) < 4
});
});
// ============================================
// SECTION 6: Facilities & Logistics
// ============================================
const facilitiesSection = form.addSubform('facilities', {
title: 'Facilities & Organization'
});
facilitiesSection.addRow(row => {
row.addStarRating('facilitiesRating', {
label: 'Rate the overall facilities (fields, courts, equipment)',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('organizationRating', {
label: 'Rate the camp organization (schedule, communication)',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
// ============================================
// SECTION 7: Would Recommend
// ============================================
const recommendSection = form.addSubform('recommend', {
title: 'Recommendation'
});
recommendSection.addRow(row => {
row.addRatingScale('npsScore', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'How likely are you to recommend this camp to other parents?'
: 'How likely are you to recommend this camp to friends?';
},
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true,
alignment: 'center'
});
});
recommendSection.addRow(row => {
row.addRadioButton('returnNext', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? 'Will your child return next year?'
: 'Will you return next year?';
},
options: [
{ id: 'definitely', name: 'Definitely yes!' },
{ id: 'probably', name: 'Probably yes' },
{ id: 'maybe', name: 'Maybe/Undecided' },
{ id: 'unlikely', name: 'Probably not' },
{ id: 'no', name: 'Definitely not' }
],
orientation: 'vertical',
isVisible: () => recommendSection.ratingScale('npsScore')?.value() !== null
});
});
// ============================================
// SECTION 8: Open Feedback
// ============================================
const feedbackSection = form.addSubform('feedback', {
title: 'Additional Feedback'
});
feedbackSection.addRow(row => {
row.addTextarea('bestPart', {
label: () => {
const type = respondentSection.radioButton('respondentType')?.value();
return type === 'parent'
? "What was your child's favorite part of camp?"
: 'What was your favorite part of camp?';
},
placeholder: 'Tell us what stood out...',
rows: 2,
autoExpand: true
});
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('improvements', {
label: 'What could we improve for next year?',
placeholder: 'Your suggestions help us get better...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => funSection.emojiRating('funRating')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const camperName = respondentSection.textbox('camperName')?.value();
const funRating = funSection.emojiRating('funRating')?.value();
const coaching = coachingSection.starRating('overallCoaching')?.value();
const skillImprovement = skillsSection.slider('skillImprovement')?.value();
const safety = safetySection.starRating('safetyRating')?.value();
const nps = recommendSection.ratingScale('npsScore')?.value();
const npsCategory = recommendSection.ratingScale('npsScore')?.npsCategory();
if (!funRating) return '';
const funLabels: Record<string, string> = {
'sad': 'Not Fun',
'down': 'Not Great',
'neutral': 'Okay',
'happy': 'Fun!',
'excited': 'Amazing!'
};
let summary = `Camp Feedback Summary\n`;
summary += `${'═'.repeat(24)}\n\n`;
if (camperName) {
summary += `Camper: ${camperName}\n`;
}
summary += `Fun Factor: ${funLabels[funRating] || funRating}\n`;
if (coaching !== null && coaching !== undefined) {
summary += `Coaching: ${coaching}/5 stars\n`;
}
if (skillImprovement !== undefined) {
summary += `Skills Improved: ${skillImprovement}%\n`;
}
if (safety !== null && safety !== undefined) {
summary += `Safety: ${safety}/5 stars\n`;
}
if (nps !== null && nps !== undefined) {
summary += `\nNPS: ${nps}/10 (${npsCategory})\n`;
}
return summary;
},
customStyles: () => {
const funRating = funSection.emojiRating('funRating')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (funRating === 'happy' || funRating === 'excited') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #ea580c' };
} else if (funRating === 'sad' || funRating === 'down') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
} else {
return { ...baseStyles, backgroundColor: '#f3f4f6', borderLeft: '4px solid #9ca3af' };
}
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => respondentSection.radioButton('respondentType')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thanks for the Feedback!',
message: () => {
const camperName = respondentSection.textbox('camperName')?.value();
const returnNext = recommendSection.radioButton('returnNext')?.value();
let msg = 'Your feedback helps us create an even better camp experience. ';
if (returnNext === 'definitely' || returnNext === 'probably') {
msg += `We can't wait to see ${camperName || 'you'} back next year!`;
} else {
msg += 'We hope to see you again in the future!';
}
return msg;
}
});
}