export function telehealthFeedback(form: FormTs) {
// Telehealth Visit Feedback - Virtual healthcare experience survey
// Demonstrates: Slider, StarRating, EmojiRating, RatingScale (NPS), MatrixQuestion, ThumbRating, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Telehealth Visit Feedback',
computedValue: () => 'Help us improve your virtual care experience',
customStyles: {
backgroundColor: '#0891b2',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
form.addRow(row => {
row.addTextPanel('confidentiality', {
computedValue: () => 'Your feedback is confidential and will be used to improve our telehealth services.',
customStyles: {
backgroundColor: '#ecfeff',
padding: '12px',
borderRadius: '8px',
fontSize: '14px',
textAlign: 'center',
fontStyle: 'italic'
}
});
});
// ============================================
// SECTION 1: Visit Information
// ============================================
const visitInfo = form.addSubform('visitInfo', {
title: 'Visit Details'
});
visitInfo.addRow(row => {
row.addDropdown('visitType', {
label: 'Type of Visit',
options: [
{ id: 'primary-care', name: 'Primary Care' },
{ id: 'specialist', name: 'Specialist Consultation' },
{ id: 'mental-health', name: 'Mental Health' },
{ id: 'follow-up', name: 'Follow-up Visit' },
{ id: 'urgent', name: 'Urgent Care' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select visit type',
isRequired: true
}, '1fr');
row.addDropdown('device', {
label: 'Device Used',
options: [
{ id: 'smartphone', name: 'Smartphone' },
{ id: 'tablet', name: 'Tablet' },
{ id: 'laptop', name: 'Laptop' },
{ id: 'desktop', name: 'Desktop Computer' }
],
placeholder: 'Select device'
}, '1fr');
});
visitInfo.addRow(row => {
row.addRadioButton('firstTelehealth', {
label: 'Was this your first telehealth visit?',
options: [
{ id: 'yes', name: 'Yes, this was my first virtual visit' },
{ id: 'no-first-here', name: 'No, but first with this provider' },
{ id: 'no-experienced', name: 'No, I have used telehealth before' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 2: Technical Quality
// ============================================
const techSection = form.addSubform('technical', {
title: 'Technical Quality',
isVisible: () => visitInfo.dropdown('visitType')?.value() !== null,
customStyles: () => {
const videoQ = techSection.slider('videoQuality')?.value() || 0;
const audioQ = techSection.slider('audioQuality')?.value() || 0;
const avg = (videoQ + audioQ) / 2;
if (avg >= 80) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (avg >= 50) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
if (avg > 0) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' };
}
});
techSection.addRow(row => {
row.addTextPanel('techInstructions', {
computedValue: () => 'Rate the technical aspects of your video visit (0 = Very Poor, 100 = Excellent)',
customStyles: {
fontSize: '14px',
color: '#64748b',
marginBottom: '8px'
}
});
});
techSection.addRow(row => {
row.addSlider('videoQuality', {
label: () => {
const val = techSection.slider('videoQuality')?.value() || 0;
if (val >= 80) return 'Video Quality: Excellent';
if (val >= 60) return 'Video Quality: Good';
if (val >= 40) return 'Video Quality: Fair';
if (val >= 20) return 'Video Quality: Poor';
return 'Video Quality';
},
min: 0,
max: 100,
step: 5,
defaultValue: 75,
unit: '%',
showValue: true
}, '1fr');
row.addSlider('audioQuality', {
label: () => {
const val = techSection.slider('audioQuality')?.value() || 0;
if (val >= 80) return 'Audio Quality: Excellent';
if (val >= 60) return 'Audio Quality: Good';
if (val >= 40) return 'Audio Quality: Fair';
if (val >= 20) return 'Audio Quality: Poor';
return 'Audio Quality';
},
min: 0,
max: 100,
step: 5,
defaultValue: 75,
unit: '%',
showValue: true
}, '1fr');
});
techSection.addRow(row => {
row.addSlider('connectionStability', {
label: () => {
const val = techSection.slider('connectionStability')?.value() || 0;
if (val >= 80) return 'Connection Stability: Very Stable';
if (val >= 60) return 'Connection Stability: Mostly Stable';
if (val >= 40) return 'Connection Stability: Some Issues';
return 'Connection Stability: Unstable';
},
min: 0,
max: 100,
step: 5,
defaultValue: 75,
unit: '%',
showValue: true
});
});
// Technical issues section
const techIssues = form.addSubform('techIssues', {
title: 'Technical Issues Encountered',
isVisible: () => {
const videoQ = techSection.slider('videoQuality')?.value() || 100;
const audioQ = techSection.slider('audioQuality')?.value() || 100;
const conn = techSection.slider('connectionStability')?.value() || 100;
return videoQ < 60 || audioQ < 60 || conn < 60;
},
customStyles: {
backgroundColor: '#fef3c7',
padding: '16px',
borderRadius: '8px'
}
});
techIssues.addRow(row => {
row.addCheckboxList('issuesEncountered', {
label: 'What issues did you experience?',
options: [
{ id: 'frozen-video', name: 'Video froze or lagged' },
{ id: 'pixelated', name: 'Pixelated or blurry video' },
{ id: 'no-video', name: 'Video did not work' },
{ id: 'audio-cutting', name: 'Audio kept cutting out' },
{ id: 'echo', name: 'Echo or feedback' },
{ id: 'no-audio', name: 'Could not hear provider' },
{ id: 'disconnected', name: 'Got disconnected' },
{ id: 'login-issues', name: 'Trouble joining the call' }
],
orientation: 'vertical'
});
});
techIssues.addRow(row => {
row.addTextarea('techComments', {
label: 'Additional technical comments',
placeholder: 'Describe any other technical issues...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 3: Platform Usability
// ============================================
const usabilitySection = form.addSubform('usability', {
title: 'Platform Experience',
isVisible: () => visitInfo.dropdown('visitType')?.value() !== null
});
usabilitySection.addRow(row => {
row.addMatrixQuestion('platformRating', {
label: 'Rate the telehealth platform',
rows: [
{ id: 'ease-join', label: 'Easy to join the visit', isRequired: true },
{ id: 'waiting-room', label: 'Virtual waiting room experience', isRequired: false },
{ id: 'navigation', label: 'Easy to navigate/use controls', isRequired: false },
{ id: 'notifications', label: 'Clear appointment reminders', isRequired: false }
],
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 4: Care Quality
// ============================================
const careSection = form.addSubform('care', {
title: 'Quality of Care',
isVisible: () => visitInfo.dropdown('visitType')?.value() !== null,
customStyles: () => {
const rating = careSection.starRating('providerRating')?.value() || 0;
if (rating >= 4) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (rating >= 3) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
if (rating >= 1) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' };
}
});
careSection.addRow(row => {
row.addStarRating('providerRating', {
label: 'How would you rate your healthcare provider?',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
careSection.addRow(row => {
row.addMatrixQuestion('careQuality', {
label: 'Rate the following aspects of your care:',
rows: [
{ id: 'listening', label: 'Provider listened to my concerns', isRequired: true },
{ id: 'explanation', label: 'Clear explanation of diagnosis/treatment', isRequired: true },
{ id: 'questions', label: 'Opportunity to ask questions', isRequired: false },
{ id: 'time', label: 'Adequate time for the visit', isRequired: false },
{ id: 'empathy', label: 'Provider showed empathy and care', isRequired: false },
{ id: 'instructions', label: 'Clear follow-up instructions', isRequired: false }
],
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: Overall Experience
// ============================================
const overallSection = form.addSubform('overall', {
title: 'Overall Experience',
isVisible: () => careSection.starRating('providerRating')?.value() !== null
});
overallSection.addRow(row => {
row.addEmojiRating('overallFeeling', {
label: 'How do you feel about your telehealth experience?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addThumbRating('teleVsInPerson', {
label: 'Would you use telehealth again instead of an in-person visit for similar concerns?',
showLabels: true,
upLabel: 'Yes, telehealth works for me',
downLabel: 'No, prefer in-person',
alignment: 'center',
size: 'lg'
});
});
overallSection.addRow(row => {
row.addRatingScale('recommendNPS', {
preset: 'nps',
label: 'How likely are you to recommend our telehealth services?',
showSegmentColors: true,
showCategoryLabel: true,
alignment: 'center',
showConfettiOnPromoter: true
});
});
// ============================================
// SECTION 6: Conditional Follow-up
// ============================================
const positiveSection = form.addSubform('positiveFollowup', {
title: 'What We Did Well',
isVisible: () => {
const nps = overallSection.ratingScale('recommendNPS')?.npsCategory();
return nps === 'promoter';
},
customStyles: { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' }
});
positiveSection.addRow(row => {
row.addSuggestionChips('positives', {
label: 'What did you appreciate most?',
suggestions: [
{ id: 'convenience', name: 'Convenience' },
{ id: 'no-travel', name: 'No travel needed' },
{ id: 'quick-access', name: 'Quick access to care' },
{ id: 'comfort', name: 'Comfort of home' },
{ id: 'provider', name: 'Great provider' },
{ id: 'easy-tech', name: 'Easy technology' },
{ id: 'time-saved', name: 'Time saved' },
{ id: 'safety', name: 'Reduced exposure risk' }
],
max: 4,
alignment: 'center'
});
});
const improvementSection = form.addSubform('improvementFollowup', {
title: 'How Can We Improve?',
isVisible: () => {
const nps = overallSection.ratingScale('recommendNPS')?.npsCategory();
return nps === 'detractor' || nps === 'passive';
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
improvementSection.addRow(row => {
row.addSuggestionChips('improvements', {
label: 'What areas need improvement?',
suggestions: [
{ id: 'video-quality', name: 'Video quality' },
{ id: 'audio-quality', name: 'Audio quality' },
{ id: 'platform', name: 'Platform usability' },
{ id: 'wait-time', name: 'Waiting time' },
{ id: 'provider-manner', name: 'Provider bedside manner' },
{ id: 'visit-length', name: 'Visit length' },
{ id: 'follow-up', name: 'Follow-up process' },
{ id: 'prefer-inperson', name: 'Prefer in-person visits' }
],
max: 4,
alignment: 'center'
});
});
improvementSection.addSpacer();
improvementSection.addRow(row => {
row.addTextarea('improvementComments', {
label: 'Please share specific suggestions for improvement',
placeholder: 'Your feedback helps us improve...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 7: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => overallSection.ratingScale('recommendNPS')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const visitType = visitInfo.dropdown('visitType')?.value() || '';
const providerRating = careSection.starRating('providerRating')?.value();
const videoQ = techSection.slider('videoQuality')?.value() || 0;
const audioQ = techSection.slider('audioQuality')?.value() || 0;
const nps = overallSection.ratingScale('recommendNPS')?.npsCategory();
const useTelehealth = overallSection.thumbRating('teleVsInPerson')?.value();
if (!providerRating) return '';
const visitTypes: Record<string, string> = {
'primary-care': 'Primary Care',
'specialist': 'Specialist',
'mental-health': 'Mental Health',
'follow-up': 'Follow-up',
'urgent': 'Urgent Care',
'other': 'Other'
};
const avgTech = Math.round((videoQ + audioQ) / 2);
const techRating = avgTech >= 80 ? 'Excellent' : avgTech >= 60 ? 'Good' : avgTech >= 40 ? 'Fair' : 'Poor';
let summary = `TELEHEALTH FEEDBACK\n`;
summary += `${'═'.repeat(25)}\n\n`;
if (visitType) {
summary += `Visit Type: ${visitTypes[visitType] || visitType}\n`;
}
summary += `\nProvider Rating: ${'★'.repeat(providerRating)}${'☆'.repeat(5 - providerRating)} (${providerRating}/5)\n`;
summary += `Technical Quality: ${techRating} (${avgTech}%)\n`;
if (nps) {
const emoji = nps === 'promoter' ? '🎉' : nps === 'passive' ? '😐' : '😟';
summary += `\n${emoji} NPS: ${nps.charAt(0).toUpperCase() + nps.slice(1)}\n`;
}
if (useTelehealth) {
summary += `\nWould use again: ${useTelehealth === 'up' ? 'Yes' : 'No'}`;
}
return summary;
},
customStyles: () => {
const nps = overallSection.ratingScale('recommendNPS')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (nps === 'promoter') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (nps === 'passive') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else if (nps === 'detractor') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #0891b2' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => overallSection.ratingScale('recommendNPS')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your feedback helps us improve our telehealth services. We appreciate you taking the time to share your experience.'
});
}