export function onlineCourseFeedbackSurvey(form: FormTs) {
// Online Course Feedback - E-learning evaluation form
// Demonstrates: MatrixQuestion, StarRating, Slider, RatingScale (Likert), EmojiRating, SuggestionChips, Integer
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Course Feedback',
computedValue: () => 'Your feedback shapes better learning experiences for everyone.',
customStyles: {
background: 'linear-gradient(135deg, #4f46e5 0%, #6366f1 100%)',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Course Information
// ============================================
const courseSection = form.addSubform('courseSection', {
title: 'Course Information'
});
courseSection.addRow(row => {
row.addTextbox('courseName', {
label: 'Course name',
placeholder: 'Enter the course title...',
isRequired: true
}, '2fr');
row.addDropdown('courseProgress', {
label: 'How much have you completed?',
options: [
{ id: '25', name: 'Less than 25%' },
{ id: '50', name: '25-50%' },
{ id: '75', name: '50-75%' },
{ id: '90', name: '75-90%' },
{ id: '100', name: 'Completed 100%' }
],
placeholder: 'Select progress...',
isRequired: true
}, '1fr');
});
courseSection.addRow(row => {
row.addInteger('hoursSpent', {
label: 'Hours you spent on this course',
min: 1,
max: 200,
placeholder: 'e.g., 15'
}, '1fr');
row.addDropdown('learningGoal', {
label: 'Why did you take this course?',
options: [
{ id: 'skill', name: 'Learn new skill' },
{ id: 'career', name: 'Career advancement' },
{ id: 'certification', name: 'Get certification' },
{ id: 'hobby', name: 'Personal interest/hobby' },
{ id: 'job-req', name: 'Job requirement' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select reason...'
}, '1fr');
});
// ============================================
// SECTION 2: Content Quality
// ============================================
const contentSection = form.addSubform('contentSection', {
title: 'Content Quality'
});
contentSection.addRow(row => {
row.addMatrixQuestion('contentMatrix', {
label: 'Rate the course content:',
rows: [
{ id: 'relevance', label: 'Relevance to my goals', isRequired: true },
{ id: 'depth', label: 'Depth and completeness', isRequired: true },
{ id: 'clarity', label: 'Clarity of explanations', isRequired: true },
{ id: 'examples', label: 'Quality of examples', isRequired: false },
{ id: 'exercises', label: 'Practical exercises', isRequired: false },
{ id: 'updated', label: 'Up-to-date content', isRequired: false }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
contentSection.addSpacer();
contentSection.addRow(row => {
row.addRatingScale('contentDifficulty', {
label: 'How would you rate the difficulty level?',
preset: 'custom',
min: 1,
max: 5,
lowLabel: 'Too easy',
highLabel: 'Too difficult',
alignment: 'center'
});
});
contentSection.addRow(row => {
row.addTextPanel('difficultyFeedback', {
computedValue: () => {
const level = contentSection.ratingScale('contentDifficulty')?.value() ?? 3;
if (level === 1) return 'Content may be below your current level';
if (level === 2) return 'Fairly easy - good for fundamentals';
if (level === 3) return 'Just right - appropriate challenge';
if (level === 4) return 'Challenging but manageable';
if (level === 5) return 'Very challenging - may need prerequisites';
return '';
},
customStyles: () => {
const level = contentSection.ratingScale('contentDifficulty')?.value() ?? 3;
const baseStyle = { padding: '8px 16px', borderRadius: '6px', textAlign: 'center' };
if (level === 3) return { ...baseStyle, backgroundColor: '#d1fae5', color: '#065f46' };
if (level <= 2) return { ...baseStyle, backgroundColor: '#dbeafe', color: '#1e40af' };
return { ...baseStyle, backgroundColor: '#fef3c7', color: '#92400e' };
},
isVisible: () => contentSection.ratingScale('contentDifficulty')?.value() !== null
});
});
// ============================================
// SECTION 3: Instructor Evaluation
// ============================================
const instructorSection = form.addSubform('instructorSection', {
title: 'Instructor Evaluation'
});
instructorSection.addRow(row => {
row.addStarRating('instructorKnowledge', {
label: 'Subject matter expertise',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
instructorSection.addRow(row => {
row.addStarRating('instructorClarity', {
label: 'Clarity of teaching',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
instructorSection.addRow(row => {
row.addStarRating('instructorEngagement', {
label: 'Engagement and enthusiasm',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
// Instructor feedback for low scores
instructorSection.addSpacer();
instructorSection.addRow(row => {
row.addTextarea('instructorFeedback', {
label: 'Any specific feedback for the instructor?',
placeholder: 'What could they improve? What did they do well?',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 4: Platform & Technical Experience
// ============================================
const platformSection = form.addSubform('platformSection', {
title: 'Platform & Technical Experience'
});
platformSection.addRow(row => {
row.addStarRating('videoQuality', {
label: 'Video/audio quality',
maxStars: 5,
size: 'md',
showCounter: true
}, '1fr');
row.addStarRating('platformEase', {
label: 'Platform ease of use',
maxStars: 5,
size: 'md',
showCounter: true
}, '1fr');
});
platformSection.addRow(row => {
row.addStarRating('mobileExperience', {
label: 'Mobile experience (if applicable)',
maxStars: 5,
size: 'md',
showCounter: true
}, '1fr');
row.addStarRating('downloadOptions', {
label: 'Offline/download options',
maxStars: 5,
size: 'md',
showCounter: true
}, '1fr');
});
// Technical issues
platformSection.addSpacer();
platformSection.addRow(row => {
row.addThumbRating('hadTechIssues', {
label: 'Did you experience any technical issues?',
showLabels: true,
upLabel: 'Yes, had issues',
downLabel: 'No problems',
size: 'lg',
alignment: 'center'
});
});
platformSection.addRow(row => {
row.addCheckboxList('techIssues', {
label: 'What issues did you encounter?',
options: [
{ id: 'buffering', name: 'Video buffering/loading' },
{ id: 'audio', name: 'Audio problems' },
{ id: 'mobile', name: 'Mobile compatibility' },
{ id: 'navigation', name: 'Navigation/finding content' },
{ id: 'progress', name: 'Progress not saving' },
{ id: 'quizzes', name: 'Quiz/exercise issues' },
{ id: 'certificates', name: 'Certificate problems' },
{ id: 'other', name: 'Other issues' }
],
orientation: 'vertical',
isVisible: () => platformSection.thumbRating('hadTechIssues')?.value() === 'up'
});
});
// ============================================
// SECTION 5: Learning Outcomes
// ============================================
const outcomesSection = form.addSubform('outcomesSection', {
title: 'Learning Outcomes'
});
outcomesSection.addRow(row => {
row.addRatingScale('skillImprovement', {
label: 'How much did your skills improve?',
preset: 'likert-5',
lowLabel: 'Not at all',
highLabel: 'Significantly',
alignment: 'center'
});
});
outcomesSection.addRow(row => {
row.addRatingScale('confidenceGain', {
label: 'How confident are you applying what you learned?',
preset: 'likert-5',
lowLabel: 'Not confident',
highLabel: 'Very confident',
alignment: 'center'
});
});
outcomesSection.addSpacer();
outcomesSection.addRow(row => {
row.addThumbRating('metExpectations', {
label: 'Did this course meet your expectations?',
showLabels: true,
upLabel: 'Yes, met or exceeded',
downLabel: 'No, fell short',
size: 'lg',
alignment: 'center'
});
});
// Expectations follow-up
outcomesSection.addRow(row => {
row.addTextarea('expectationGap', {
label: 'What was missing from your expectations?',
placeholder: 'Help us understand what you hoped to learn...',
rows: 2,
isVisible: () => outcomesSection.thumbRating('metExpectations')?.value() === 'down'
});
});
// ============================================
// SECTION 6: Engagement & Pacing
// ============================================
const engagementSection = form.addSubform('engagementSection', {
title: 'Engagement & Pacing'
});
engagementSection.addRow(row => {
row.addSlider('engagementLevel', {
label: 'How engaged were you throughout the course?',
min: 1,
max: 10,
step: 1,
defaultValue: 7,
showValue: true,
unit: '/10'
});
});
engagementSection.addRow(row => {
row.addRadioButton('pacingFeedback', {
label: 'How was the course pacing?',
options: [
{ id: 'too-slow', name: 'Too slow - could be condensed' },
{ id: 'slightly-slow', name: 'Slightly slow' },
{ id: 'just-right', name: 'Just right' },
{ id: 'slightly-fast', name: 'Slightly fast' },
{ id: 'too-fast', name: 'Too fast - needed more time' }
],
orientation: 'vertical'
});
});
engagementSection.addRow(row => {
row.addSuggestionChips('favoriteElements', {
label: 'What kept you engaged? (select all that apply)',
suggestions: [
{ id: 'videos', name: 'Video lessons' },
{ id: 'quizzes', name: 'Quizzes & tests' },
{ id: 'projects', name: 'Projects' },
{ id: 'discussions', name: 'Discussions' },
{ id: 'instructor', name: 'Instructor style' },
{ id: 'examples', name: 'Real examples' },
{ id: 'resources', name: 'Resources' },
{ id: 'community', name: 'Community' }
],
alignment: 'left'
});
});
// ============================================
// SECTION 7: Overall Assessment
// ============================================
const overallSection = form.addSubform('overallSection', {
title: 'Overall Assessment',
customStyles: () => {
const mood = overallSection.emojiRating('overallSatisfaction')?.value();
if (mood === 'excellent' || mood === 'good') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (mood === 'very-bad' || mood === 'bad') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' };
}
});
overallSection.addRow(row => {
row.addEmojiRating('overallSatisfaction', {
label: 'Overall, how satisfied are you with this course?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addRatingScale('recommendCourse', {
label: 'How likely are you to recommend this course?',
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true,
alignment: 'center'
});
});
overallSection.addSpacer();
overallSection.addRow(row => {
row.addTextarea('bestPart', {
label: 'What was the best part of this course?',
placeholder: 'Share what you loved...',
rows: 2,
autoExpand: true
});
});
overallSection.addRow(row => {
row.addTextarea('improvementSuggestions', {
label: 'How could this course be improved?',
placeholder: 'Your suggestions help us create better courses...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => {
const satisfaction = overallSection.emojiRating('overallSatisfaction')?.value();
return satisfaction !== null;
}
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const courseName = courseSection.textbox('courseName')?.value() || 'Course';
const progress = courseSection.dropdown('courseProgress')?.value() || '?';
const hoursSpent = courseSection.integer('hoursSpent')?.value() ?? 0;
const instructorKnowledge = instructorSection.starRating('instructorKnowledge')?.value() ?? 0;
const instructorClarity = instructorSection.starRating('instructorClarity')?.value() ?? 0;
const instructorEngagement = instructorSection.starRating('instructorEngagement')?.value() ?? 0;
const instructorAvg = (instructorKnowledge + instructorClarity + instructorEngagement) / 3;
const skillImprovement = outcomesSection.ratingScale('skillImprovement')?.value() ?? 0;
const confidence = outcomesSection.ratingScale('confidenceGain')?.value() ?? 0;
const engagement = engagementSection.slider('engagementLevel')?.value() ?? 0;
const satisfaction = overallSection.emojiRating('overallSatisfaction')?.value();
const nps = overallSection.ratingScale('recommendCourse')?.value() ?? 0;
const satisfactionLabels: Record<string, string> = {
'very-bad': 'Very Unsatisfied', 'bad': 'Unsatisfied', 'neutral': 'Neutral',
'good': 'Satisfied', 'excellent': 'Very Satisfied'
};
let summary = `Course Feedback: ${courseName}\n`;
summary += '═'.repeat(35) + '\n\n';
summary += `Progress: ${progress}%\n`;
if (hoursSpent > 0) summary += `Time Invested: ${hoursSpent} hours\n`;
summary += `\nInstructor Rating: ${instructorAvg.toFixed(1)}/5\n`;
summary += ` Knowledge: ${instructorKnowledge}/5\n`;
summary += ` Clarity: ${instructorClarity}/5\n`;
summary += ` Engagement: ${instructorEngagement}/5\n`;
summary += `\nLearning Outcomes:\n`;
summary += ` Skill Improvement: ${skillImprovement}/5\n`;
summary += ` Confidence: ${confidence}/5\n`;
summary += ` Engagement: ${engagement}/10\n`;
summary += `\nOverall: ${satisfactionLabels[satisfaction || ''] || 'Not rated'}\n`;
summary += `NPS: ${nps}/10\n`;
// Insights
if (instructorAvg >= 4) {
summary += '\n✨ Strong instructor performance';
}
if (skillImprovement >= 4) {
summary += '\n✨ High skill improvement reported';
}
if (nps >= 9) {
summary += '\n✨ Promoter - likely to recommend';
}
return summary;
},
customStyles: {
backgroundColor: '#eef2ff',
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px',
borderLeft: '4px solid #6366f1'
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Course Feedback'
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your insights help improve this course for future students and guide the instructor\'s development. We appreciate you taking the time to share your experience!'
});
}