export function workshopFeedbackSurvey(form: FormTs) {
// Workshop Feedback - Post-workshop evaluation form
// Demonstrates: StarRating, Slider, MatrixQuestion, RatingScale (Likert), RadioButton, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Workshop Feedback',
computedValue: () => 'Your feedback helps us create better learning experiences.',
customStyles: {
backgroundColor: '#7c3aed',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Workshop Details
// ============================================
const detailsSection = form.addSubform('detailsSection', {
title: 'Workshop Information'
});
detailsSection.addRow(row => {
row.addTextbox('workshopName', {
label: 'Workshop name/title',
placeholder: 'e.g., Advanced JavaScript Workshop'
}, '1fr');
row.addDatepicker('workshopDate', {
label: 'Date attended',
maxDate: () => new Date().toISOString().split('T')[0]
}, '1fr');
});
detailsSection.addRow(row => {
row.addDropdown('experienceLevel', {
label: 'Your experience level before the workshop',
options: [
{ id: 'beginner', name: 'Beginner - New to this topic' },
{ id: 'intermediate', name: 'Intermediate - Some experience' },
{ id: 'advanced', name: 'Advanced - Experienced practitioner' },
{ id: 'expert', name: 'Expert - Deep expertise' }
]
});
});
// ============================================
// SECTION 2: Overall Satisfaction
// ============================================
const satisfactionSection = form.addSubform('satisfactionSection', {
title: 'Overall Satisfaction',
customStyles: () => {
const rating = satisfactionSection.starRating('overall')?.value();
if (rating === null || rating === undefined) return { padding: '16px' };
if (rating >= 4) return { backgroundColor: '#ede9fe', padding: '16px', borderRadius: '8px' };
if (rating >= 3) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
}
});
satisfactionSection.addRow(row => {
row.addStarRating('overall', {
label: 'How would you rate this workshop overall?',
maxStars: 5,
size: 'xl',
alignment: 'center',
showCounter: true,
showConfettiOnMax: true
});
});
satisfactionSection.addRow(row => {
row.addEmojiRating('engagement', {
label: 'How engaged did you feel during the workshop?',
preset: 'satisfaction',
size: 'md',
showLabels: true,
alignment: 'center',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
});
// ============================================
// SECTION 3: Content & Pacing
// ============================================
const contentSection = form.addSubform('contentSection', {
title: 'Content & Pacing',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
contentSection.addRow(row => {
row.addSlider('difficulty', {
label: 'Difficulty level',
min: 1,
max: 5,
step: 1,
showValue: true,
unit: '',
defaultValue: 3
}, '1fr');
row.addSlider('pacing', {
label: 'Pacing of the workshop',
min: 1,
max: 5,
step: 1,
showValue: true,
unit: '',
defaultValue: 3
}, '1fr');
});
contentSection.addRow(row => {
row.addTextPanel('scaleLabels', {
computedValue: () => {
const difficulty = contentSection.slider('difficulty')?.value() || 3;
const pacing = contentSection.slider('pacing')?.value() || 3;
const diffLabels = ['Too Easy', 'Easy', 'Just Right', 'Challenging', 'Too Difficult'];
const paceLabels = ['Too Slow', 'Slow', 'Just Right', 'Fast', 'Too Fast'];
return `📊 Difficulty: ${diffLabels[difficulty - 1]} | ⏱️ Pacing: ${paceLabels[pacing - 1]}`;
},
customStyles: {
backgroundColor: '#f5f3ff',
padding: '12px',
borderRadius: '8px',
textAlign: 'center',
fontSize: '14px'
}
});
});
contentSection.addRow(row => {
row.addSlider('practicalBalance', {
label: 'Balance between theory and hands-on practice',
min: 1,
max: 5,
step: 1,
showValue: true,
defaultValue: 3
});
});
contentSection.addRow(row => {
row.addTextPanel('balanceLabel', {
computedValue: () => {
const balance = contentSection.slider('practicalBalance')?.value() || 3;
const labels = ['All Theory', 'Mostly Theory', 'Good Balance', 'Mostly Hands-on', 'All Hands-on'];
return `📚 ${labels[balance - 1]}`;
},
customStyles: {
backgroundColor: '#f5f3ff',
padding: '8px 12px',
borderRadius: '6px',
textAlign: 'center',
fontSize: '13px'
}
});
});
// ============================================
// SECTION 4: Workshop Quality Matrix
// ============================================
const qualitySection = form.addSubform('qualitySection', {
title: 'Quality Assessment',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
qualitySection.addRow(row => {
row.addMatrixQuestion('qualityMatrix', {
label: 'Please rate the following aspects',
rows: [
{ id: 'relevance', label: 'Content relevance to my work', isRequired: true },
{ id: 'organization', label: 'Workshop organization & structure' },
{ id: 'materials', label: 'Quality of materials/handouts' },
{ id: 'exercises', label: 'Hands-on exercises & activities' },
{ id: 'examples', label: 'Real-world examples used' },
{ id: 'objectives', label: 'Clear learning objectives' }
],
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
});
});
// ============================================
// SECTION 5: Facilitator Rating
// ============================================
const facilitatorSection = form.addSubform('facilitatorSection', {
title: 'Facilitator Evaluation',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
facilitatorSection.addRow(row => {
row.addStarRating('facilitatorKnowledge', {
label: 'Subject matter expertise',
maxStars: 5,
size: 'md',
alignment: 'left'
}, '1fr');
row.addStarRating('facilitatorPresentation', {
label: 'Presentation skills',
maxStars: 5,
size: 'md',
alignment: 'left'
}, '1fr');
});
facilitatorSection.addRow(row => {
row.addStarRating('facilitatorEngagement', {
label: 'Ability to engage participants',
maxStars: 5,
size: 'md',
alignment: 'left'
}, '1fr');
row.addStarRating('facilitatorQuestions', {
label: 'Handling of questions',
maxStars: 5,
size: 'md',
alignment: 'left'
}, '1fr');
});
// ============================================
// SECTION 6: Learning Outcomes
// ============================================
const learningSection = form.addSubform('learningSection', {
title: 'Learning Outcomes',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
learningSection.addRow(row => {
row.addRatingScale('confidenceBefore', {
label: 'Your confidence level BEFORE the workshop',
preset: 'likert-5',
lowLabel: 'Not confident',
highLabel: 'Very confident',
size: 'sm'
});
});
learningSection.addRow(row => {
row.addRatingScale('confidenceAfter', {
label: 'Your confidence level AFTER the workshop',
preset: 'likert-5',
lowLabel: 'Not confident',
highLabel: 'Very confident',
size: 'sm'
});
});
learningSection.addRow(row => {
row.addTextPanel('confidenceChange', {
computedValue: () => {
const before = learningSection.ratingScale('confidenceBefore')?.value();
const after = learningSection.ratingScale('confidenceAfter')?.value();
if (before === null || before === undefined || after === null || after === undefined) {
return '';
}
const change = after - before;
if (change > 0) return `📈 Confidence increased by ${change} level${change > 1 ? 's' : ''}!`;
if (change < 0) return `📉 Confidence decreased by ${Math.abs(change)} level${Math.abs(change) > 1 ? 's' : ''}`;
return '➡️ Confidence level unchanged';
},
customStyles: () => {
const before = learningSection.ratingScale('confidenceBefore')?.value();
const after = learningSection.ratingScale('confidenceAfter')?.value();
const change = (after || 0) - (before || 0);
const base = { padding: '10px', borderRadius: '6px', textAlign: 'center', fontSize: '14px' };
if (change > 0) return { ...base, backgroundColor: '#d1fae5', color: '#065f46' };
if (change < 0) return { ...base, backgroundColor: '#fee2e2', color: '#991b1b' };
return { ...base, backgroundColor: '#f3f4f6', color: '#374151' };
},
isVisible: () => {
const before = learningSection.ratingScale('confidenceBefore')?.value();
const after = learningSection.ratingScale('confidenceAfter')?.value();
return before !== null && before !== undefined && after !== null && after !== undefined;
}
});
});
learningSection.addRow(row => {
row.addThumbRating('wouldApply', {
label: 'Will you apply what you learned?',
size: 'lg',
showLabels: true,
upLabel: 'Yes, definitely!',
downLabel: 'Probably not',
alignment: 'center'
});
});
// ============================================
// SECTION 7: Recommendations
// ============================================
const recommendSection = form.addSubform('recommendSection', {
title: 'Recommendation',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
recommendSection.addRow(row => {
row.addRadioButton('recommend', {
label: 'Would you recommend this workshop to colleagues?',
options: [
{ id: 'definitely', name: 'Definitely yes' },
{ id: 'probably', name: 'Probably yes' },
{ id: 'maybe', name: 'Maybe' },
{ id: 'probablyNot', name: 'Probably not' },
{ id: 'definitelyNot', name: 'Definitely not' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 8: Open Feedback
// ============================================
const feedbackSection = form.addSubform('feedbackSection', {
title: 'Additional Comments',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
feedbackSection.addRow(row => {
row.addTextarea('bestPart', {
label: 'What was the most valuable part of the workshop?',
placeholder: 'Share what resonated with you most...',
rows: 2,
autoExpand: true
});
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('improvements', {
label: () => {
const rating = satisfactionSection.starRating('overall')?.value();
if (rating !== null && rating !== undefined && rating <= 3) {
return 'What should we improve for future workshops?';
}
return 'Any suggestions for improvement? (Optional)';
},
placeholder: 'Your ideas help us create better workshops...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const overall = satisfactionSection.starRating('overall')?.value();
const difficulty = contentSection.slider('difficulty')?.value();
const pacing = contentSection.slider('pacing')?.value();
const before = learningSection.ratingScale('confidenceBefore')?.value();
const after = learningSection.ratingScale('confidenceAfter')?.value();
const recommend = recommendSection.radioButton('recommend')?.value();
const wouldApply = learningSection.thumbRating('wouldApply')?.value();
if (overall === null || overall === undefined) return '';
let emoji = overall >= 4 ? '🎓' : overall >= 3 ? '📚' : '📝';
let status = overall >= 4 ? 'Excellent' : overall >= 3 ? 'Good' : 'Needs Improvement';
let summary = `${emoji} Workshop Feedback Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `⭐ Overall Rating: ${overall}/5 (${status})\n`;
if (difficulty) {
const diffLabels = ['Too Easy', 'Easy', 'Just Right', 'Challenging', 'Too Difficult'];
summary += `📊 Difficulty: ${diffLabels[difficulty - 1]}\n`;
}
if (pacing) {
const paceLabels = ['Too Slow', 'Slow', 'Just Right', 'Fast', 'Too Fast'];
summary += `⏱️ Pacing: ${paceLabels[pacing - 1]}\n`;
}
if (before !== null && before !== undefined && after !== null && after !== undefined) {
const change = after - before;
const arrow = change > 0 ? '📈' : change < 0 ? '📉' : '➡️';
summary += `${arrow} Confidence: ${before} → ${after} (${change > 0 ? '+' : ''}${change})\n`;
}
if (wouldApply) {
summary += `🎯 Will apply: ${wouldApply === 'up' ? 'Yes' : 'No'}\n`;
}
if (recommend) {
const recLabels: Record<string, string> = {
'definitely': '👍👍 Definitely recommend',
'probably': '👍 Probably recommend',
'maybe': '🤔 Maybe',
'probablyNot': '👎 Probably not',
'definitelyNot': '👎👎 Would not recommend'
};
summary += `\n${recLabels[recommend] || recommend}`;
}
return summary;
},
customStyles: () => {
const rating = satisfactionSection.starRating('overall')?.value();
const base = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (rating !== null && rating !== undefined && rating >= 4) {
return { ...base, backgroundColor: '#ede9fe', borderLeft: '4px solid #7c3aed' };
} else if (rating !== null && rating !== undefined && rating <= 2) {
return { ...base, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...base, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => satisfactionSection.starRating('overall')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your insights will help us improve future workshops and create better learning experiences for everyone.'
});
}