export function sportsClubFeedbackForm(form: FormTs) {
// Sports Club Member Feedback Survey
// Demonstrates: RatingScale (NPS), MatrixQuestion, StarRating, SuggestionChips, Slider, CheckboxList
// Focus: Quarterly member satisfaction with facility and program ratings
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Member Feedback Survey',
computedValue: () => 'Your opinion helps us create a better club experience for everyone.',
customStyles: {
backgroundColor: '#0891b2',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Membership Info
// ============================================
const memberSection = form.addSubform('memberSection', {
title: 'About Your Membership'
});
memberSection.addRow(row => {
row.addDropdown('membershipDuration', {
label: 'How long have you been a member?',
options: [
{ id: 'new', name: 'Less than 3 months' },
{ id: '3-6', name: '3-6 months' },
{ id: '6-12', name: '6-12 months' },
{ id: '1-2', name: '1-2 years' },
{ id: '2-5', name: '2-5 years' },
{ id: '5+', name: 'Over 5 years' }
],
placeholder: 'Select duration'
});
});
memberSection.addRow(row => {
row.addDropdown('visitFrequency', {
label: 'How often do you visit the club?',
options: [
{ id: 'daily', name: 'Daily' },
{ id: '4-5', name: '4-5 times per week' },
{ id: '2-3', name: '2-3 times per week' },
{ id: 'weekly', name: 'Once a week' },
{ id: 'few-month', name: 'A few times per month' },
{ id: 'rarely', name: 'Rarely' }
],
placeholder: 'Select frequency'
});
});
// ============================================
// SECTION 2: NPS - Would Recommend
// ============================================
const npsSection = form.addSubform('npsSection', {
title: 'Would You Recommend Us?',
isVisible: () => !!memberSection.dropdown('membershipDuration')?.value(),
customStyles: () => {
const score = npsSection.ratingScale('npsScore')?.value();
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return { backgroundColor: '#dcfce7', padding: '20px', borderRadius: '12px' };
if (category === 'passive') return { backgroundColor: '#fef9c3', padding: '20px', borderRadius: '12px' };
if (category === 'detractor') return { backgroundColor: '#fee2e2', padding: '20px', borderRadius: '12px' };
return { padding: '20px', borderRadius: '12px', border: '2px dashed #d1d5db' };
}
});
npsSection.addRow(row => {
row.addRatingScale('npsScore', {
preset: 'nps',
label: 'How likely are you to recommend our club to a friend or colleague?',
showSegmentColors: true,
showCategoryLabel: true,
showConfettiOnPromoter: true,
isRequired: true
});
});
npsSection.addRow(row => {
row.addTextarea('npsReason', {
label: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return 'Awesome! What do you love most about our club?';
if (category === 'passive') return 'What would make you rate us higher?';
if (category === 'detractor') return 'We\'re sorry to hear that. What can we improve?';
return 'Tell us why you chose this score';
},
placeholder: 'Your feedback helps us improve...',
rows: 2,
autoExpand: true,
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
});
// ============================================
// SECTION 3: Facility Ratings Matrix
// ============================================
const facilitySection = form.addSubform('facilitySection', {
title: 'Facility Ratings',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
facilitySection.addRow(row => {
row.addMatrixQuestion('facilityMatrix', {
label: 'Please rate the following facilities:',
rows: [
{ id: 'gym-floor', label: 'Gym floor / Weight room' },
{ id: 'cardio', label: 'Cardio equipment area' },
{ id: 'locker', label: 'Locker rooms & showers' },
{ id: 'pool', label: 'Pool / Aquatic facilities' },
{ id: 'courts', label: 'Courts (tennis, basketball, etc.)' },
{ id: 'group-fitness', label: 'Group fitness studios' },
{ id: 'parking', label: 'Parking & accessibility' }
],
columns: [
{ id: 'excellent', label: 'Excellent' },
{ id: 'good', label: 'Good' },
{ id: 'average', label: 'Average' },
{ id: 'poor', label: 'Poor' },
{ id: 'na', label: 'N/A' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 4: Staff & Service
// ============================================
const staffSection = form.addSubform('staffSection', {
title: 'Staff & Service',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
staffSection.addRow(row => {
row.addStarRating('frontDesk', {
label: 'Front desk staff',
maxStars: 5,
size: 'lg',
showCounter: true
}, '1fr');
row.addStarRating('trainers', {
label: 'Personal trainers',
maxStars: 5,
size: 'lg',
showCounter: true
}, '1fr');
});
staffSection.addRow(row => {
row.addStarRating('instructors', {
label: 'Class instructors',
maxStars: 5,
size: 'lg',
showCounter: true
}, '1fr');
row.addStarRating('maintenance', {
label: 'Cleanliness & maintenance',
maxStars: 5,
size: 'lg',
showCounter: true
}, '1fr');
});
// ============================================
// SECTION 5: Programs & Classes
// ============================================
const programSection = form.addSubform('programSection', {
title: 'Programs & Classes',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
programSection.addRow(row => {
row.addCheckboxList('programsUsed', {
label: 'Which programs do you participate in? (Select all that apply)',
options: [
{ id: 'weights', name: 'Weight training' },
{ id: 'cardio', name: 'Cardio equipment' },
{ id: 'group-classes', name: 'Group fitness classes' },
{ id: 'yoga', name: 'Yoga / Pilates' },
{ id: 'swimming', name: 'Swimming' },
{ id: 'personal-training', name: 'Personal training' },
{ id: 'sports-leagues', name: 'Sports leagues' },
{ id: 'kids-programs', name: 'Kids programs' },
{ id: 'spa', name: 'Spa / Wellness services' }
],
orientation: 'vertical'
});
});
programSection.addSpacer();
programSection.addRow(row => {
row.addRatingScale('classVariety', {
label: 'How satisfied are you with the variety of classes offered?',
preset: 'satisfaction',
variant: 'segmented',
size: 'md'
});
});
programSection.addRow(row => {
row.addRatingScale('classSchedule', {
label: 'How convenient are the class schedules for you?',
preset: 'satisfaction',
variant: 'segmented',
size: 'md'
});
});
// ============================================
// SECTION 6: Value & Pricing
// ============================================
const valueSection = form.addSubform('valueSection', {
title: 'Value & Membership',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
valueSection.addRow(row => {
row.addSlider('valueForMoney', {
label: 'How would you rate the value for money of your membership?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
showValue: true,
unit: '/10'
});
});
valueSection.addRow(row => {
row.addTextPanel('valueNote', {
computedValue: () => {
const value = valueSection.slider('valueForMoney')?.value();
if (!value) return '';
if (value <= 3) return 'We hear you - let us know how we can provide better value.';
if (value <= 5) return 'There\'s room for improvement. Your suggestions help!';
if (value <= 7) return 'Good, but we can do better!';
if (value <= 9) return 'Great! We\'re glad you\'re getting value from your membership.';
return 'Fantastic! We love having you as a member!';
},
customStyles: () => {
const value = valueSection.slider('valueForMoney')?.value();
const bg = value && value >= 7 ? '#dcfce7' : value && value >= 5 ? '#fef3c7' : '#fee2e2';
return {
backgroundColor: bg,
padding: '10px',
borderRadius: '6px',
textAlign: 'center'
};
},
isVisible: () => !!valueSection.slider('valueForMoney')?.value()
});
});
// ============================================
// SECTION 7: What We Do Well
// ============================================
const strengthsSection = form.addSubform('strengthsSection', {
title: 'What We Do Well',
isVisible: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
return category === 'promoter' || category === 'passive';
},
customStyles: { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' }
});
strengthsSection.addRow(row => {
row.addSuggestionChips('clubStrengths', {
label: 'What do you value most about our club? (Select up to 4)',
suggestions: [
{ id: 'equipment', name: 'Modern equipment' },
{ id: 'cleanliness', name: 'Cleanliness' },
{ id: 'staff', name: 'Friendly staff' },
{ id: 'classes', name: 'Class variety' },
{ id: 'location', name: 'Location' },
{ id: 'hours', name: 'Operating hours' },
{ id: 'community', name: 'Community / atmosphere' },
{ id: 'amenities', name: 'Amenities (pool, sauna, etc.)' },
{ id: 'price', name: 'Membership price' },
{ id: 'trainers', name: 'Quality trainers' }
],
max: 4,
alignment: 'left'
});
});
// ============================================
// SECTION 8: Improvement Areas
// ============================================
const improvementSection = form.addSubform('improvementSection', {
title: 'Areas for Improvement',
isVisible: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
return category === 'detractor' || category === 'passive';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
improvementSection.addRow(row => {
row.addSuggestionChips('improvementNeeds', {
label: 'What should we improve? (Select all that apply)',
suggestions: [
{ id: 'equipment', name: 'Update equipment' },
{ id: 'cleanliness', name: 'Cleanliness' },
{ id: 'crowding', name: 'Reduce crowding' },
{ id: 'hours', name: 'Better hours' },
{ id: 'classes', name: 'More class options' },
{ id: 'locker', name: 'Locker rooms' },
{ id: 'parking', name: 'Parking' },
{ id: 'staff', name: 'Staff training' },
{ id: 'pricing', name: 'Better pricing' },
{ id: 'app', name: 'Mobile app / booking' }
],
alignment: 'left'
});
});
improvementSection.addSpacer();
improvementSection.addRow(row => {
row.addTextarea('improvementDetails', {
label: 'Tell us more about what we can improve',
placeholder: 'Your detailed suggestions help us prioritize improvements...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 9: Additional Comments
// ============================================
const commentsSection = form.addSubform('commentsSection', {
title: 'Additional Comments',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
commentsSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Is there anything else you\'d like to share with us?',
placeholder: 'Ideas, concerns, compliments - we want to hear it all!',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 10: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const nps = npsSection.ratingScale('npsScore')?.value();
const category = npsSection.ratingScale('npsScore')?.npsCategory();
const duration = memberSection.dropdown('membershipDuration')?.value();
const frequency = memberSection.dropdown('visitFrequency')?.value();
const value = valueSection.slider('valueForMoney')?.value();
const frontDesk = staffSection.starRating('frontDesk')?.value();
const trainers = staffSection.starRating('trainers')?.value();
if (nps === null || nps === undefined) return '';
const durationLabels: Record<string, string> = {
'new': 'New member', '3-6': '3-6 months', '6-12': '6-12 months',
'1-2': '1-2 years', '2-5': '2-5 years', '5+': '5+ years'
};
let summary = '🏋️ Member Feedback Summary\n';
summary += '━'.repeat(28) + '\n\n';
summary += `NPS Score: ${nps}/10 (${category?.charAt(0).toUpperCase()}${category?.slice(1)})\n`;
if (duration) summary += `Membership: ${durationLabels[duration] || duration}\n`;
if (value) summary += `Value Rating: ${value}/10\n`;
if (frontDesk) summary += `Front Desk: ${'★'.repeat(frontDesk)}${'☆'.repeat(5 - frontDesk)}\n`;
if (trainers) summary += `Trainers: ${'★'.repeat(trainers)}${'☆'.repeat(5 - trainers)}\n`;
return summary;
},
customStyles: () => {
const category = npsSection.ratingScale('npsScore')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (category === 'promoter') return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #22c55e' };
if (category === 'passive') return { ...baseStyles, backgroundColor: '#fef9c3', borderLeft: '4px solid #eab308' };
if (category === 'detractor') return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
return { ...baseStyles, backgroundColor: '#f3f4f6' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => npsSection.ratingScale('npsScore')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You!',
message: 'Your feedback helps us create a better club experience. We review every response and use your input to improve our facilities and services. See you at the club!'
});
}