export function knowledgeBaseFeedback(form: FormTs) {
// Knowledge Base Article Feedback Form
// Demonstrates: ThumbRating, RatingScale, EmojiRating, MatrixQuestion, CheckboxList, SuggestionChips
// State to track if user found article helpful
const wasHelpful = form.state<boolean | null>(null);
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Article Feedback',
computedValue: () => 'Help us improve our knowledge base by sharing your thoughts.',
customStyles: {
backgroundColor: '#8b5cf6',
color: 'white',
padding: '20px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Primary Helpfulness Question
// ============================================
const helpfulSection = form.addSubform('helpful', {
title: 'Was This Article Helpful?',
customStyles: () => {
const rating = helpfulSection.thumbRating('wasHelpful')?.value();
if (rating === 'up') return { backgroundColor: '#dcfce7', padding: '16px', borderRadius: '8px' };
if (rating === 'down') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' };
}
});
helpfulSection.addRow(row => {
row.addThumbRating('wasHelpful', {
label: 'Did this article answer your question?',
showLabels: true,
upLabel: 'Yes, it helped',
downLabel: 'No, it didn\'t',
size: 'lg',
alignment: 'center',
onValueChange: (value) => {
wasHelpful.set(value === 'up' ? true : value === 'down' ? false : null);
}
});
});
// Show emoji rating after thumb rating
helpfulSection.addSpacer({ height: '12px', isVisible: () => helpfulSection.thumbRating('wasHelpful')?.value() !== null });
helpfulSection.addRow(row => {
row.addEmojiRating('sentiment', {
label: () => {
const rating = helpfulSection.thumbRating('wasHelpful')?.value();
if (rating === 'up') return 'How satisfied are you with this article?';
return 'How frustrated did this make you feel?';
},
preset: () => {
const rating = helpfulSection.thumbRating('wasHelpful')?.value();
return rating === 'down' ? 'effort' : 'satisfaction';
},
size: 'md',
showLabels: true,
alignment: 'center',
isVisible: () => helpfulSection.thumbRating('wasHelpful')?.value() !== null
});
});
// ============================================
// SECTION 2: Article Quality Rating (when helpful)
// ============================================
const qualitySection = form.addSubform('quality', {
title: 'Article Quality',
isVisible: () => wasHelpful() === true,
customStyles: { backgroundColor: '#f0fdf4', padding: '16px', borderRadius: '8px' }
});
qualitySection.addRow(row => {
row.addMatrixQuestion('qualityRatings', {
label: 'Rate the following aspects of this article:',
rows: [
{ id: 'clarity', label: 'Clarity of explanation', isRequired: true },
{ id: 'completeness', label: 'Completeness of information' },
{ id: 'accuracy', label: 'Accuracy of content' },
{ id: 'organization', label: 'Logical organization' },
{ id: 'findability', label: 'Easy to find' }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
qualitySection.addSpacer({ height: '16px' });
qualitySection.addRow(row => {
row.addSuggestionChips('whatHelped', {
label: 'What was most helpful? (select up to 3)',
suggestions: [
{ id: 'steps', name: 'Step-by-step instructions' },
{ id: 'screenshots', name: 'Screenshots/Images' },
{ id: 'examples', name: 'Examples provided' },
{ id: 'video', name: 'Video content' },
{ id: 'links', name: 'Related links' },
{ id: 'faq', name: 'FAQ section' }
],
max: 3,
alignment: 'center'
});
});
// ============================================
// SECTION 3: What Was Missing (when not helpful)
// ============================================
const missingSection = form.addSubform('missing', {
title: 'What Was Missing?',
isVisible: () => wasHelpful() === false,
customStyles: { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' }
});
missingSection.addRow(row => {
row.addCheckboxList('missingElements', {
label: 'What was lacking in this article? (select all that apply)',
options: [
{ id: 'outdated', name: 'Information is outdated' },
{ id: 'incomplete', name: 'Missing important details' },
{ id: 'confusing', name: 'Explanation is confusing' },
{ id: 'wrong_topic', name: 'Doesn\'t address my issue' },
{ id: 'no_examples', name: 'Needs more examples' },
{ id: 'no_screenshots', name: 'Needs screenshots/visuals' },
{ id: 'too_technical', name: 'Too technical' },
{ id: 'too_basic', name: 'Too basic/not detailed enough' }
],
orientation: 'vertical'
});
});
missingSection.addSpacer({ height: '16px' });
missingSection.addRow(row => {
row.addTextarea('whatLookingFor', {
label: 'What were you trying to accomplish?',
placeholder: 'Describe what you were looking for or trying to do...',
rows: 3,
autoExpand: true,
isRequired: true
});
});
missingSection.addSpacer({ height: '12px' });
missingSection.addRow(row => {
row.addTextarea('improvementSuggestions', {
label: 'How could we improve this article?',
placeholder: 'Tell us what information or changes would make this article helpful...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 4: Content Gap Identification
// ============================================
const gapsSection = form.addSubform('gaps', {
title: 'Suggest New Topics',
isVisible: () => helpfulSection.thumbRating('wasHelpful')?.value() !== null
});
gapsSection.addRow(row => {
row.addRatingScale('contentCoverage', {
preset: 'likert-5',
label: 'How well does our knowledge base cover topics you need?',
lowLabel: 'Very poorly',
highLabel: 'Very well',
size: 'md',
alignment: 'center'
});
});
gapsSection.addSpacer({ height: '16px' });
gapsSection.addRow(row => {
row.addSuggestionChips('topicsWanted', {
label: 'What topics would you like to see added?',
suggestions: [
{ id: 'getting_started', name: 'Getting started guides' },
{ id: 'troubleshooting', name: 'Troubleshooting guides' },
{ id: 'best_practices', name: 'Best practices' },
{ id: 'integrations', name: 'Integrations' },
{ id: 'api_docs', name: 'API documentation' },
{ id: 'video_tutorials', name: 'Video tutorials' },
{ id: 'use_cases', name: 'Use case examples' },
{ id: 'comparisons', name: 'Feature comparisons' }
],
alignment: 'center'
});
});
gapsSection.addSpacer({ height: '12px' });
gapsSection.addRow(row => {
row.addTextarea('topicSuggestion', {
label: 'Any specific topic or question you\'d like us to cover?',
placeholder: 'Describe an article topic that would help you...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 5: Contact for Follow-up (when not helpful)
// ============================================
const contactSection = form.addSubform('contact', {
title: 'Need More Help?',
isVisible: () => wasHelpful() === false
});
contactSection.addRow(row => {
row.addTextPanel('supportNote', {
computedValue: () => "Since this article didn't help, would you like our support team to assist you?",
customStyles: {
backgroundColor: '#fef3c7',
padding: '12px',
borderRadius: '8px',
fontSize: '14px'
}
});
});
contactSection.addRow(row => {
row.addCheckbox('wantSupport', {
label: 'Yes, please connect me with support'
});
});
contactSection.addRow(row => {
row.addEmail('email', {
label: 'Your email address',
placeholder: 'support@example.com',
isRequired: () => contactSection.checkbox('wantSupport')?.value() === true,
isVisible: () => contactSection.checkbox('wantSupport')?.value() === true
});
});
// ============================================
// SECTION 6: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => helpfulSection.thumbRating('wasHelpful')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const helpful = helpfulSection.thumbRating('wasHelpful')?.value();
const sentiment = helpfulSection.emojiRating('sentiment')?.value();
const coverage = gapsSection.ratingScale('contentCoverage')?.value();
const missing = missingSection.checkboxList('missingElements')?.value() || [];
const whatHelped = qualitySection.suggestionChips('whatHelped')?.value() || [];
if (helpful === null) return '';
let emoji = helpful === 'up' ? '✅' : '❌';
let summary = `${emoji} Article Feedback Summary\n`;
summary += `${'═'.repeat(28)}\n\n`;
summary += `📖 Article Helpful: ${helpful === 'up' ? 'Yes' : 'No'}\n`;
if (sentiment) {
const sentimentLabels: Record<string, string> = {
'very-hard': '😫 Very Frustrated',
'hard': '😓 Frustrated',
'neutral': '😐 Neutral',
'easy': '💪 Satisfied',
'very-easy': '🚀 Very Satisfied',
'very-bad': '😢 Very Unsatisfied',
'bad': '😕 Unsatisfied',
'good': '😊 Satisfied',
'excellent': '😃 Very Satisfied'
};
summary += `💭 Sentiment: ${sentimentLabels[sentiment] || sentiment}\n`;
}
if (coverage !== null && coverage !== undefined) {
summary += `📚 KB Coverage Rating: ${coverage}/5\n`;
}
if (helpful === 'up' && whatHelped.length > 0) {
summary += `\n✨ Most Helpful: ${whatHelped.length} element(s) selected`;
}
if (helpful === 'down' && missing.length > 0) {
summary += `\n⚠️ Issues Found: ${missing.length} item(s) selected`;
}
return summary;
},
customStyles: () => {
const helpful = helpfulSection.thumbRating('wasHelpful')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (helpful === 'up') {
return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #22c55e' };
} else {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: () => {
const helpful = helpfulSection.thumbRating('wasHelpful')?.value();
if (helpful === 'down') return 'Submit & Get Help';
return 'Submit Feedback';
},
isVisible: () => helpfulSection.thumbRating('wasHelpful')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: () => {
const helpful = helpfulSection.thumbRating('wasHelpful')?.value();
if (helpful === 'up') return 'Thanks for the positive feedback!';
return 'Thank you for your feedback';
},
message: () => {
const helpful = helpfulSection.thumbRating('wasHelpful')?.value();
const wantSupport = contactSection.checkbox('wantSupport')?.value();
if (helpful === 'up') {
return "We're glad this article helped! Your feedback helps us create better content.";
}
if (wantSupport) {
return "We'll use your feedback to improve this article. Our support team will reach out to help you shortly.";
}
return "We're sorry this article didn't help. We'll review your feedback and work on improving it.";
}
});
}