export function gymFeedbackSurvey(form: FormTs) {
// Gym & Fitness Center Feedback - Multi-page member satisfaction survey
// Demonstrates: Pages (multi-page wizard), StarRating, MatrixQuestion, CheckboxList, EmojiRating, ThumbRating, Timepicker
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Gym Member Feedback',
computedValue: () => 'Help us make your fitness experience even better!',
customStyles: {
background: 'linear-gradient(135deg, #dc2626 0%, #f97316 100%)',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// MULTI-PAGE WIZARD
// ============================================
const pages = form.addPages('surveyPages', {
heightMode: 'current-page'
});
// ============================================
// PAGE 1: Visit Details
// ============================================
const page1 = pages.addPage('visitDetails');
page1.addRow(row => {
row.addTextPanel('page1Title', {
label: 'Page 1 of 4: Your Visit',
customStyles: { fontWeight: 'bold', fontSize: '18px', color: '#dc2626', marginBottom: '8px' }
});
});
page1.addRow(row => {
row.addDropdown('visitFrequency', {
label: 'How often do you visit our gym?',
options: [
{ id: 'daily', name: 'Daily (5+ times/week)' },
{ id: 'frequent', name: 'Frequently (3-4 times/week)' },
{ id: 'regular', name: 'Regularly (1-2 times/week)' },
{ id: 'occasional', name: 'Occasionally (few times/month)' },
{ id: 'rare', name: 'Rarely (once a month or less)' },
{ id: 'first', name: 'This was my first visit' }
],
isRequired: true
}, '1fr');
row.addTimepicker('usualTime', {
label: 'What time do you usually work out?',
defaultValue: '18:00'
}, '1fr');
});
page1.addRow(row => {
row.addCheckboxList('areasUsed', {
label: 'Which areas do you typically use? (select all that apply)',
options: [
{ id: 'cardio', name: 'Cardio area (treadmills, bikes, ellipticals)' },
{ id: 'weights', name: 'Free weights area' },
{ id: 'machines', name: 'Weight machines' },
{ id: 'functional', name: 'Functional training / CrossFit area' },
{ id: 'classes', name: 'Group fitness classes' },
{ id: 'pool', name: 'Swimming pool' },
{ id: 'spa', name: 'Spa / Sauna / Steam room' },
{ id: 'locker', name: 'Locker rooms / Showers' }
],
orientation: 'vertical',
isRequired: true
});
});
page1.addRow(row => {
row.addEmojiRating('visitMood', {
label: 'How do you feel after a typical workout here?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
page1.addRow(row => {
row.addButton('nextPage1', {
label: 'Next: Equipment & Facilities',
onClick: () => pages.goToPage('equipment')
});
});
// ============================================
// PAGE 2: Equipment & Facilities
// ============================================
const page2 = pages.addPage('equipment');
page2.addRow(row => {
row.addTextPanel('page2Title', {
label: 'Page 2 of 4: Equipment & Facilities',
customStyles: { fontWeight: 'bold', fontSize: '18px', color: '#dc2626', marginBottom: '8px' }
});
});
page2.addRow(row => {
row.addMatrixQuestion('equipmentRating', {
label: 'Rate the following aspects of our equipment:',
rows: [
{ id: 'variety', label: 'Equipment variety', isRequired: true },
{ id: 'quality', label: 'Equipment quality/condition' },
{ id: 'availability', label: 'Equipment availability' },
{ id: 'cleanliness', label: 'Equipment cleanliness' },
{ id: 'maintenance', label: 'Maintenance / Working order' }
],
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
});
});
page2.addRow(row => {
row.addStarRating('cleanlinessOverall', {
label: 'Overall facility cleanliness',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('lockerRooms', {
label: 'Locker room & shower cleanliness',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
page2.addSpacer();
page2.addRow(row => {
row.addTextarea('equipmentIssues', {
label: 'Any equipment issues or suggestions?',
placeholder: 'E.g., broken machines, equipment requests, cleanliness concerns...',
rows: 2,
autoExpand: true
});
});
page2.addRow(row => {
row.addButton('backPage2', {
label: 'Back',
onClick: () => pages.goToPage('visitDetails')
});
row.addButton('nextPage2', {
label: 'Next: Staff & Classes',
onClick: () => pages.goToPage('staffClasses')
});
});
// ============================================
// PAGE 3: Staff & Classes
// ============================================
const page3 = pages.addPage('staffClasses');
page3.addRow(row => {
row.addTextPanel('page3Title', {
label: 'Page 3 of 4: Staff & Classes',
customStyles: { fontWeight: 'bold', fontSize: '18px', color: '#dc2626', marginBottom: '8px' }
});
});
// Staff ratings
const staffSubform = page3.addSubform('staffSection', {
title: 'Staff Experience'
});
staffSubform.addRow(row => {
row.addMatrixQuestion('staffRating', {
label: 'Rate our staff on the following:',
rows: [
{ id: 'friendliness', label: 'Friendliness', isRequired: true },
{ id: 'knowledge', label: 'Knowledge & expertise' },
{ id: 'availability', label: 'Availability when needed' },
{ id: 'professionalism', label: 'Professionalism' }
],
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
});
});
// Classes section - conditional
const classesSubform = page3.addSubform('classesSection', {
title: 'Group Fitness Classes',
isVisible: () => {
const areas = page1.checkboxList('areasUsed')?.value() || [];
return areas.includes('classes');
}
});
classesSubform.addRow(row => {
row.addCheckboxList('classTypes', {
label: 'Which classes have you attended?',
options: [
{ id: 'yoga', name: 'Yoga / Pilates' },
{ id: 'spinning', name: 'Spinning / Cycling' },
{ id: 'hiit', name: 'HIIT / Circuit training' },
{ id: 'zumba', name: 'Zumba / Dance' },
{ id: 'strength', name: 'Strength / Body pump' },
{ id: 'boxing', name: 'Boxing / Kickboxing' },
{ id: 'aqua', name: 'Aqua fitness' },
{ id: 'other', name: 'Other classes' }
],
orientation: 'vertical'
});
});
classesSubform.addRow(row => {
row.addStarRating('classQuality', {
label: 'Overall quality of classes',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('instructorRating', {
label: 'Instructor quality',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
classesSubform.addRow(row => {
row.addRadioButton('classSchedule', {
label: 'Are class schedules convenient for you?',
options: [
{ id: 'perfect', name: 'Yes, perfect timing' },
{ id: 'mostly', name: 'Mostly, but some gaps' },
{ id: 'limited', name: 'Limited options for my schedule' },
{ id: 'poor', name: 'Poor - need more variety' }
],
orientation: 'vertical'
});
});
page3.addRow(row => {
row.addButton('backPage3', {
label: 'Back',
onClick: () => pages.goToPage('equipment')
});
row.addButton('nextPage3', {
label: 'Next: Overall Experience',
onClick: () => pages.goToPage('overall')
});
});
// ============================================
// PAGE 4: Overall Experience
// ============================================
const page4 = pages.addPage('overall');
page4.addRow(row => {
row.addTextPanel('page4Title', {
label: 'Page 4 of 4: Overall Experience',
customStyles: { fontWeight: 'bold', fontSize: '18px', color: '#dc2626', marginBottom: '8px' }
});
});
page4.addRow(row => {
row.addStarRating('overallRating', {
label: 'Overall gym experience',
maxStars: 5,
size: 'xl',
alignment: 'center',
showConfettiOnMax: true
});
});
page4.addRow(row => {
row.addRatingScale('valueForMoney', {
preset: 'likert-5',
label: 'The membership fee is good value for what I get',
lowLabel: 'Strongly Disagree',
highLabel: 'Strongly Agree',
alignment: 'center'
});
});
page4.addRow(row => {
row.addThumbRating('recommend', {
label: 'Would you recommend our gym to friends?',
showLabels: true,
upLabel: 'Yes, I would!',
downLabel: 'Not right now',
size: 'lg',
alignment: 'center'
});
});
// Follow-up for not recommending
page4.addRow(row => {
row.addTextarea('notRecommendReason', {
label: 'What would need to change for you to recommend us?',
placeholder: 'Your honest feedback helps us improve...',
rows: 2,
isVisible: () => page4.thumbRating('recommend')?.value() === 'down'
});
});
page4.addRow(row => {
row.addSuggestionChips('improvements', {
label: 'What would you most like us to improve?',
suggestions: [
{ id: 'equipment', name: 'More/better equipment' },
{ id: 'cleanliness', name: 'Cleanliness' },
{ id: 'hours', name: 'Operating hours' },
{ id: 'classes', name: 'Class variety' },
{ id: 'crowding', name: 'Less crowding' },
{ id: 'staff', name: 'Staff service' },
{ id: 'parking', name: 'Parking' },
{ id: 'price', name: 'Lower prices' }
],
max: 3,
alignment: 'center'
});
});
page4.addSpacer();
page4.addRow(row => {
row.addTextarea('finalComments', {
label: 'Any other comments or suggestions?',
placeholder: 'We value all feedback...',
rows: 3,
autoExpand: true
});
});
// Summary
const summarySubform = page4.addSubform('summary', {
title: 'Your Feedback Summary',
customStyles: () => {
const overall = page4.starRating('overallRating')?.value() ?? 0;
if (overall >= 4) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (overall <= 2 && overall > 0) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' };
},
isVisible: () => (page4.starRating('overallRating')?.value() ?? 0) > 0
});
summarySubform.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const frequency = page1.dropdown('visitFrequency')?.value();
const mood = page1.emojiRating('visitMood')?.value();
const areas = page1.checkboxList('areasUsed')?.value() || [];
const overall = page4.starRating('overallRating')?.value() ?? 0;
const recommend = page4.thumbRating('recommend')?.value();
const improvements = page4.suggestionChips('improvements')?.value() || [];
const freqLabels: Record<string, string> = {
'daily': '5+ times/week', 'frequent': '3-4 times/week',
'regular': '1-2 times/week', 'occasional': 'Few times/month',
'rare': 'Once a month or less', 'first': 'First visit'
};
let summary = 'Gym Feedback Summary\n';
summary += '═'.repeat(25) + '\n\n';
summary += `Visit Frequency: ${freqLabels[frequency || ''] || 'Not specified'}\n`;
summary += `Areas Used: ${areas.length} areas\n`;
summary += `Overall Rating: ${'★'.repeat(overall)}${'☆'.repeat(5 - overall)}\n`;
summary += `Would Recommend: ${recommend === 'up' ? 'Yes' : recommend === 'down' ? 'No' : 'Not answered'}\n`;
if (improvements.length > 0) {
summary += `\nTop Improvements: ${improvements.join(', ')}`;
}
return summary;
},
customStyles: {
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
}
});
});
page4.addRow(row => {
row.addButton('backPage4', {
label: 'Back',
onClick: () => pages.goToPage('staffClasses')
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => pages.currentPageIndex() === 3
});
form.configureCompletionScreen({
type: 'text',
title: 'Thanks for your feedback!',
message: 'Your input helps us create a better gym experience for everyone. Keep crushing your fitness goals!'
});
}