export function assignmentFeedbackForm(form: FormTs) {
// Assignment Difficulty Feedback - Student effort and learning assessment
// Demonstrates: Slider, StarRating, EmojiRating, RatingScale (Likert), MatrixQuestion, Integer, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Assignment Feedback',
computedValue: () => 'Help us improve by sharing your experience with this assignment.',
customStyles: {
backgroundColor: '#7c3aed',
color: 'white',
padding: '28px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Assignment Details
// ============================================
const detailsSection = form.addSubform('details', {
title: 'Assignment Details'
});
detailsSection.addRow(row => {
row.addTextbox('assignmentName', {
label: 'Assignment Name/Number',
placeholder: 'e.g., Assignment 3: Data Structures',
isRequired: true
}, '2fr');
row.addDropdown('courseModule', {
label: 'Course Module',
options: [
{ id: 'mod1', name: 'Module 1' },
{ id: 'mod2', name: 'Module 2' },
{ id: 'mod3', name: 'Module 3' },
{ id: 'mod4', name: 'Module 4' },
{ id: 'mod5', name: 'Module 5' },
{ id: 'final', name: 'Final Project' }
],
placeholder: 'Select module...'
}, '1fr');
});
// ============================================
// SECTION 2: Time & Effort
// ============================================
const effortSection = form.addSubform('effort', {
title: 'Time & Effort'
});
effortSection.addRow(row => {
row.addInteger('timeSpent', {
label: 'Approximate time spent (hours)',
placeholder: 'Hours',
min: 0,
max: 100,
isRequired: true
}, '1fr');
row.addInteger('expectedTime', {
label: 'Expected time (from syllabus)',
placeholder: 'Hours',
min: 0,
max: 100
}, '1fr');
});
effortSection.addRow(row => {
row.addTextPanel('timeComparison', {
computedValue: () => {
const actual = effortSection.integer('timeSpent')?.value();
const expected = effortSection.integer('expectedTime')?.value();
if (actual === null || actual === undefined || expected === null || expected === undefined || expected === 0) return '';
const ratio = actual / expected;
if (ratio <= 0.75) return '⚡ You finished faster than expected!';
if (ratio <= 1.25) return '✓ Time spent was about as expected.';
if (ratio <= 2) return '⚠️ This took longer than expected.';
return '🔴 Significantly more time than expected - please share why below.';
},
customStyles: () => {
const actual = effortSection.integer('timeSpent')?.value();
const expected = effortSection.integer('expectedTime')?.value();
if (actual === null || actual === undefined || expected === null || expected === undefined || expected === 0) {
return { display: 'none' };
}
const ratio = actual / expected;
const baseStyles = { padding: '12px', borderRadius: '6px', fontSize: '14px', marginTop: '8px' };
if (ratio <= 0.75) return { ...baseStyles, backgroundColor: '#d1fae5', color: '#065f46' };
if (ratio <= 1.25) return { ...baseStyles, backgroundColor: '#e0f2fe', color: '#0369a1' };
if (ratio <= 2) return { ...baseStyles, backgroundColor: '#fef3c7', color: '#92400e' };
return { ...baseStyles, backgroundColor: '#fee2e2', color: '#991b1b' };
}
});
});
effortSection.addRow(row => {
row.addSlider('effortLevel', {
label: 'Overall effort required',
min: 1,
max: 10,
step: 1,
showValue: true,
defaultValue: 5
});
});
effortSection.addRow(row => {
row.addTextPanel('effortScale', {
computedValue: () => '1 = Minimal effort • 5 = Moderate effort • 10 = Maximum effort',
customStyles: { color: '#64748b', fontSize: '12px', textAlign: 'center' }
});
});
// ============================================
// SECTION 3: Difficulty Assessment
// ============================================
const difficultySection = form.addSubform('difficulty', {
title: 'Difficulty Assessment'
});
difficultySection.addRow(row => {
row.addEmojiRating('difficultyFeeling', {
label: 'How did you feel about the difficulty level?',
preset: 'effort',
size: 'lg',
alignment: 'center',
showLabels: true
});
});
difficultySection.addRow(row => {
row.addRatingScale('difficultyMatch', {
label: 'Was the difficulty appropriate for this stage of the course?',
preset: 'likert-5',
lowLabel: 'Too Easy',
highLabel: 'Too Hard',
alignment: 'center'
});
});
difficultySection.addRow(row => {
row.addMatrixQuestion('difficultyBreakdown', {
label: 'Rate difficulty of each aspect:',
rows: [
{ id: 'understanding', label: 'Understanding requirements', isRequired: true },
{ id: 'concepts', label: 'Applying concepts', isRequired: true },
{ id: 'technical', label: 'Technical implementation', isRequired: false },
{ id: 'time-mgmt', label: 'Time management', isRequired: false },
{ id: 'resources', label: 'Finding resources', isRequired: false }
],
columns: [
{ id: '1', label: 'Very Easy' },
{ id: '2', label: 'Easy' },
{ id: '3', label: 'Moderate' },
{ id: '4', label: 'Difficult' },
{ id: '5', label: 'Very Difficult' }
],
fullWidth: true,
striped: true
});
});
// ============================================
// SECTION 4: Challenges & Struggles
// ============================================
const challengesSection = form.addSubform('challenges', {
title: 'Challenges Encountered'
});
challengesSection.addRow(row => {
row.addCheckboxList('challengeTypes', {
label: 'What challenges did you face? (Select all that apply)',
options: [
{ id: 'unclear', name: 'Unclear instructions or requirements' },
{ id: 'prereqs', name: 'Missing prerequisite knowledge' },
{ id: 'resources', name: 'Difficulty finding resources/references' },
{ id: 'technical', name: 'Technical issues (software, tools)' },
{ id: 'time', name: 'Time constraints' },
{ id: 'complex', name: 'Concept was too complex' },
{ id: 'scope', name: 'Assignment scope too large' },
{ id: 'feedback', name: 'Needed more examples or feedback' },
{ id: 'none', name: 'No significant challenges' }
],
orientation: 'vertical'
});
});
challengesSection.addSpacer({ height: '15px' });
challengesSection.addRow(row => {
row.addTextarea('challengeDetails', {
label: 'Please describe your biggest challenge',
placeholder: 'What specific concept, task, or requirement was most challenging?',
rows: 3,
autoExpand: true,
isVisible: () => {
const challenges = challengesSection.checkboxList('challengeTypes')?.value() || [];
return challenges.length > 0 && !challenges.includes('none');
}
});
});
// ============================================
// SECTION 5: Learning Value
// ============================================
const learningSection = form.addSubform('learning', {
title: 'Learning Value'
});
learningSection.addRow(row => {
row.addStarRating('learningValue', {
label: 'How much did you learn from this assignment?',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
});
});
learningSection.addRow(row => {
row.addRatingScale('relevance', {
label: 'How relevant was this assignment to course objectives?',
preset: 'likert-5',
lowLabel: 'Not Relevant',
highLabel: 'Highly Relevant',
alignment: 'center'
});
});
learningSection.addRow(row => {
row.addThumbRating('wouldRecommend', {
label: 'Would you recommend keeping this assignment for future students?',
showLabels: true,
upLabel: 'Yes, keep it',
downLabel: 'No, revise it',
alignment: 'center'
});
});
// ============================================
// SECTION 6: Resources Used
// ============================================
const resourcesSection = form.addSubform('resources', {
title: 'Resources & Support'
});
resourcesSection.addRow(row => {
row.addCheckboxList('resourcesUsed', {
label: 'What resources did you use?',
options: [
{ id: 'lectures', name: 'Lecture notes/videos' },
{ id: 'textbook', name: 'Course textbook' },
{ id: 'slides', name: 'Presentation slides' },
{ id: 'examples', name: 'Provided examples' },
{ id: 'classmates', name: 'Classmates/study groups' },
{ id: 'instructor', name: 'Instructor/TA help' },
{ id: 'online', name: 'Online tutorials/videos' },
{ id: 'ai', name: 'AI assistance (ChatGPT, etc.)' },
{ id: 'forums', name: 'Online forums (Stack Overflow, etc.)' }
],
orientation: 'vertical'
});
});
resourcesSection.addRow(row => {
row.addRadioButton('resourceSufficiency', {
label: 'Were the provided resources sufficient?',
options: [
{ id: 'yes', name: 'Yes, fully sufficient' },
{ id: 'mostly', name: 'Mostly, needed minor external help' },
{ id: 'partially', name: 'Partially, needed significant external help' },
{ id: 'no', name: 'No, relied heavily on external resources' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 7: Improvement Suggestions
// ============================================
const suggestionsSection = form.addSubform('suggestions', {
title: 'Suggestions for Improvement'
});
suggestionsSection.addRow(row => {
row.addTextarea('improvementSuggestions', {
label: 'How could this assignment be improved?',
placeholder: 'Share specific suggestions for instructions, scope, resources, or support...',
rows: 4,
autoExpand: true
});
});
suggestionsSection.addRow(row => {
row.addTextarea('additionalSupport', {
label: 'What additional support would have helped?',
placeholder: 'E.g., more examples, office hours, tutorial videos...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Your Feedback Summary',
isVisible: () => {
const time = effortSection.integer('timeSpent')?.value();
const difficulty = difficultySection.emojiRating('difficultyFeeling')?.value();
return time !== null && time !== undefined && difficulty !== null;
}
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const timeSpent = effortSection.integer('timeSpent')?.value();
const expectedTime = effortSection.integer('expectedTime')?.value();
const difficulty = difficultySection.emojiRating('difficultyFeeling')?.value();
const learningValue = learningSection.starRating('learningValue')?.value();
const challenges = challengesSection.checkboxList('challengeTypes')?.value() || [];
const recommend = learningSection.thumbRating('wouldRecommend')?.value();
if (timeSpent === null || timeSpent === undefined) return '';
const difficultyLabels: Record<string, string> = {
'very-hard': 'Very Difficult',
'hard': 'Difficult',
'neutral': 'Moderate',
'easy': 'Easy',
'very-easy': 'Very Easy'
};
let summary = '📚 Assignment Feedback Summary\n';
summary += `${'═'.repeat(30)}\n\n`;
summary += `⏱️ Time Spent: ${timeSpent} hours`;
if (expectedTime) {
const ratio = timeSpent / expectedTime;
summary += ` (${Math.round(ratio * 100)}% of expected)\n`;
} else {
summary += '\n';
}
if (difficulty) {
summary += `📊 Difficulty: ${difficultyLabels[difficulty] || difficulty}\n`;
}
if (learningValue) {
summary += `⭐ Learning Value: ${learningValue}/5 stars\n`;
}
if (challenges.length > 0 && !challenges.includes('none')) {
summary += `\n⚠️ Challenges: ${challenges.length} reported`;
} else if (challenges.includes('none')) {
summary += `\n✅ No significant challenges`;
}
if (recommend) {
summary += `\n📝 Recommendation: ${recommend === 'up' ? 'Keep' : 'Revise'} assignment`;
}
return summary;
},
customStyles: () => {
const difficulty = difficultySection.emojiRating('difficultyFeeling')?.value();
const baseStyles = {
padding: '20px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (difficulty === 'easy' || difficulty === 'very-easy') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (difficulty === 'neutral') {
return { ...baseStyles, backgroundColor: '#e0f2fe', borderLeft: '4px solid #0ea5e9' };
} else if (difficulty === 'hard' || difficulty === 'very-hard') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#f1f5f9', borderLeft: '4px solid #94a3b8' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback'
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your insights help us improve assignments for you and future students. Keep up the great work!'
});
}