export function pageFeedbackSurvey(form: FormTs) {
// Page Helpfulness Feedback - On-Page Content Widget
// Demonstrates: ThumbRating, SuggestionChips, RadioButton, EmojiRating, Conditional Visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Was this page helpful?',
computedValue: () => 'Your feedback helps us improve our content.',
customStyles: {
backgroundColor: '#3b82f6',
color: 'white',
padding: '16px',
borderRadius: '8px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Primary Helpfulness Vote
// ============================================
const primarySection = form.addSubform('primary', {
title: ''
});
primarySection.addRow(row => {
row.addThumbRating('helpful', {
label: 'Did this page answer your question?',
size: 'lg',
showLabels: true,
upLabel: 'Yes, helpful',
downLabel: 'No, not helpful',
alignment: 'center'
});
});
// ============================================
// SECTION 2: Purpose Matching
// ============================================
const purposeSection = form.addSubform('purpose', {
title: 'About Your Visit',
isVisible: () => primarySection.thumbRating('helpful')?.value() !== null
});
purposeSection.addRow(row => {
row.addRadioButton('visitPurpose', {
label: 'What were you trying to accomplish?',
options: [
{ id: 'learn', name: 'Learn how to do something' },
{ id: 'troubleshoot', name: 'Solve a problem' },
{ id: 'research', name: 'Research before deciding' },
{ id: 'reference', name: 'Find specific information' },
{ id: 'explore', name: 'Just browsing' }
],
orientation: 'vertical'
});
});
purposeSection.addRow(row => {
row.addThumbRating('goalAchieved', {
label: 'Did you achieve your goal?',
size: 'md',
showLabels: true,
upLabel: 'Yes',
downLabel: 'Not yet',
alignment: 'center',
isVisible: () => {
const purpose = purposeSection.radioButton('visitPurpose')?.value();
return purpose !== null && purpose !== undefined && purpose !== 'explore';
}
});
});
// ============================================
// SECTION 3: Positive Feedback Path
// ============================================
const positiveSection = form.addSubform('positive', {
title: 'Glad we could help!',
isVisible: () => primarySection.thumbRating('helpful')?.value() === 'up',
customStyles: { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' }
});
positiveSection.addRow(row => {
row.addSuggestionChips('whatHelped', {
label: 'What was most helpful? (optional)',
suggestions: [
{ id: 'clear', name: 'Clear explanation' },
{ id: 'examples', name: 'Good examples' },
{ id: 'complete', name: 'Complete information' },
{ id: 'organized', name: 'Well organized' },
{ id: 'quick', name: 'Quick to find' },
{ id: 'accurate', name: 'Accurate info' }
],
alignment: 'center',
max: 3
});
});
positiveSection.addRow(row => {
row.addEmojiRating('satisfaction', {
label: 'How would you rate your overall experience?',
preset: 'satisfaction',
size: 'md',
alignment: 'center'
});
});
// ============================================
// SECTION 4: Negative Feedback Path
// ============================================
const negativeSection = form.addSubform('negative', {
title: 'Sorry about that. Help us improve:',
isVisible: () => primarySection.thumbRating('helpful')?.value() === 'down',
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
negativeSection.addRow(row => {
row.addSuggestionChips('whatsMissing', {
label: 'What was the problem?',
suggestions: [
{ id: 'incomplete', name: 'Missing information' },
{ id: 'confusing', name: 'Hard to understand' },
{ id: 'outdated', name: 'Outdated content' },
{ id: 'wrong', name: 'Incorrect info' },
{ id: 'irrelevant', name: 'Not what I needed' },
{ id: 'navigation', name: 'Hard to find' }
],
alignment: 'center'
});
});
negativeSection.addSpacer({ height: '12px' });
negativeSection.addRow(row => {
row.addTextarea('improvementSuggestion', {
label: () => {
const issues = negativeSection.suggestionChips('whatsMissing')?.value() || [];
if (issues.includes('incomplete')) return 'What information were you looking for?';
if (issues.includes('confusing')) return 'What part was confusing?';
if (issues.includes('outdated') || issues.includes('wrong')) return 'What needs to be corrected?';
return 'How can we improve this page?';
},
placeholder: 'Please share any specific details...',
rows: 3
});
});
// ============================================
// SECTION 5: Content Quality Rating
// ============================================
const qualitySection = form.addSubform('quality', {
title: 'Rate the Content',
isVisible: () => primarySection.thumbRating('helpful')?.value() !== null
});
qualitySection.addRow(row => {
row.addStarRating('clarity', {
label: 'Clarity',
maxStars: 5,
size: 'sm',
showCounter: false
}, '1fr');
row.addStarRating('completeness', {
label: 'Completeness',
maxStars: 5,
size: 'sm',
showCounter: false
}, '1fr');
row.addStarRating('usefulness', {
label: 'Usefulness',
maxStars: 5,
size: 'sm',
showCounter: false
}, '1fr');
});
// ============================================
// SECTION 6: Search Experience (for troubleshooters)
// ============================================
const searchSection = form.addSubform('search', {
title: 'Finding This Page',
isVisible: () => {
const purpose = purposeSection.radioButton('visitPurpose')?.value();
return purpose === 'troubleshoot' || purpose === 'reference';
}
});
searchSection.addRow(row => {
row.addRadioButton('howFound', {
label: 'How did you find this page?',
options: [
{ id: 'search', name: 'Search engine' },
{ id: 'site-search', name: 'Site search' },
{ id: 'navigation', name: 'Navigation/menu' },
{ id: 'link', name: 'Link from another page' },
{ id: 'direct', name: 'Bookmark/direct link' }
],
orientation: 'horizontal'
});
});
searchSection.addRow(row => {
row.addRatingScale('findability', {
label: 'How easy was it to find what you needed?',
preset: 'ces',
lowLabel: 'Very Difficult',
highLabel: 'Very Easy',
alignment: 'center',
size: 'sm'
});
});
// ============================================
// SECTION 7: Follow-Up Option
// ============================================
const followUpSection = form.addSubform('followUp', {
title: 'Stay Connected',
isVisible: () => {
const helpful = primarySection.thumbRating('helpful')?.value();
return helpful === 'down' || purposeSection.thumbRating('goalAchieved')?.value() === 'down';
}
});
followUpSection.addRow(row => {
row.addCheckbox('wantsFollowUp', {
label: "I'd like someone to follow up with me about this"
});
});
followUpSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Your email',
placeholder: 'you@example.com',
isRequired: () => followUpSection.checkbox('wantsFollowUp')?.value() === true,
isVisible: () => followUpSection.checkbox('wantsFollowUp')?.value() === true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => primarySection.thumbRating('helpful')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const helpful = primarySection.thumbRating('helpful')?.value();
const purpose = purposeSection.radioButton('visitPurpose')?.value();
const goalAchieved = purposeSection.thumbRating('goalAchieved')?.value();
const whatHelped = positiveSection.suggestionChips('whatHelped')?.value() || [];
const whatsMissing = negativeSection.suggestionChips('whatsMissing')?.value() || [];
const clarity = qualitySection.starRating('clarity')?.value();
const completeness = qualitySection.starRating('completeness')?.value();
const usefulness = qualitySection.starRating('usefulness')?.value();
const satisfaction = positiveSection.emojiRating('satisfaction')?.value();
const purposeLabels: Record<string, string> = {
'learn': 'Learning',
'troubleshoot': 'Problem solving',
'research': 'Research',
'reference': 'Reference lookup',
'explore': 'Exploring'
};
const satisfactionLabels: Record<string, string> = {
'very-bad': 'Very Dissatisfied',
'bad': 'Dissatisfied',
'neutral': 'Neutral',
'good': 'Satisfied',
'excellent': 'Very Satisfied'
};
let summary = `Page Feedback\n`;
summary += `${''.repeat(16)}\n\n`;
summary += ` Helpful: ${helpful === 'up' ? ' Yes' : ' No'}\n`;
if (purpose) {
summary += ` Purpose: ${purposeLabels[purpose] || purpose}\n`;
}
if (goalAchieved) {
summary += ` Goal Achieved: ${goalAchieved === 'up' ? 'Yes' : 'Not yet'}\n`;
}
if (helpful === 'up' && whatHelped.length > 0) {
summary += `\n Helpful aspects: ${whatHelped.length} selected\n`;
}
if (helpful === 'down' && whatsMissing.length > 0) {
summary += `\n Issues: ${whatsMissing.length} identified\n`;
}
if (clarity || completeness || usefulness) {
const avg = Math.round(((clarity || 0) + (completeness || 0) + (usefulness || 0)) /
((clarity ? 1 : 0) + (completeness ? 1 : 0) + (usefulness ? 1 : 0)));
summary += `\n Content Rating: ${avg}/5 avg\n`;
}
if (satisfaction) {
summary += `\n Satisfaction: ${satisfactionLabels[satisfaction] || satisfaction}\n`;
}
return summary;
},
customStyles: () => {
const helpful = primarySection.thumbRating('helpful')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (helpful === 'up') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
}
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: () => {
const helpful = primarySection.thumbRating('helpful')?.value();
if (helpful === 'up') return 'Send Feedback';
if (helpful === 'down') return 'Submit & Help Us Improve';
return 'Submit Feedback';
},
isVisible: () => primarySection.thumbRating('helpful')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thanks for your feedback!',
message: 'Your input helps us create better content. We review all feedback to continuously improve our documentation.'
});
}