export function hospitalDischarge(form: FormTs) {
// Hospital Discharge Feedback Form
// Demonstrates: RatingScale (Likert), MatrixQuestion, StarRating, EmojiRating,
// CheckboxList, Slider, conditional visibility, patient-friendly design
// ============================================
// STATE
// ============================================
const overallReadiness = form.state<string | null>(null);
const instructionClarity = form.state<number | null>(null);
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Discharge Experience Survey',
computedValue: () => 'Help us improve the discharge process for future patients.',
customStyles: {
background: 'linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%)',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center',
fontSize: '14px'
}
});
});
// ============================================
// SECTION 1: OVERALL READINESS
// ============================================
const readinessSection = form.addSubform('readinessSection', {
title: 'Overall Readiness',
customStyles: {
backgroundColor: '#f0f9ff',
padding: '16px',
borderRadius: '8px'
}
});
readinessSection.addRow(row => {
row.addEmojiRating('readinessFeeling', {
label: 'How ready did you feel to leave the hospital?',
preset: 'satisfaction',
size: 'lg',
alignment: 'center',
onValueChange: (v) => overallReadiness.set(v ?? null)
});
});
readinessSection.addRow(row => {
row.addRatingScale('overallDischarge', {
label: 'Rate your overall discharge experience:',
preset: 'satisfaction',
alignment: 'center'
});
});
// ============================================
// SECTION 2: DISCHARGE INSTRUCTIONS
// ============================================
const instructionsSection = form.addSubform('instructionsSection', {
title: 'Discharge Instructions',
isVisible: () => overallReadiness() !== null,
customStyles: {
backgroundColor: '#ecfdf5',
padding: '16px',
borderRadius: '8px'
}
});
instructionsSection.addRow(row => {
row.addRatingScale('instructionClarity', {
label: 'How clear were your written discharge instructions?',
preset: 'likert-5',
lowLabel: 'Very unclear',
highLabel: 'Very clear',
alignment: 'center',
onValueChange: (v) => instructionClarity.set(v ?? null)
});
});
instructionsSection.addRow(row => {
row.addMatrixQuestion('instructionTopics', {
label: 'How well were these topics explained?',
rows: [
{ id: 'medications', label: 'Medications to take', isRequired: true },
{ id: 'warning', label: 'Warning signs to watch for' },
{ id: 'restrictions', label: 'Activity restrictions' },
{ id: 'diet', label: 'Diet instructions' },
{ id: 'wound', label: 'Wound/incision care' },
{ id: 'followup', label: 'Follow-up appointments' }
],
columns: [
{ id: 'notApplicable', label: 'N/A' },
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
fullWidth: true
});
});
instructionsSection.addRow(row => {
row.addThumbRating('instructionWritten', {
label: 'Did you receive written instructions to take home?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
alignment: 'center'
});
});
// Follow-up if instructions were unclear
const unclearSection = instructionsSection.addSubform('unclearSection', {
isVisible: () => (instructionClarity() ?? 0) <= 2 && instructionClarity() !== null
});
unclearSection.addSpacer({ height: '16px' });
unclearSection.addRow(row => {
row.addCheckboxList('unclearAreas', {
label: 'Which areas were unclear?',
options: [
{ id: 'meds', name: 'Medication schedule' },
{ id: 'dosage', name: 'Medication dosages' },
{ id: 'symptoms', name: 'What symptoms to watch for' },
{ id: 'emergency', name: 'When to seek emergency care' },
{ id: 'activities', name: 'What activities to avoid' },
{ id: 'appointments', name: 'Follow-up appointment details' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 3: MEDICATION UNDERSTANDING
// ============================================
const medicationSection = form.addSubform('medicationSection', {
title: 'Medication Understanding',
isVisible: () => instructionClarity() !== null
});
medicationSection.addRow(row => {
row.addRadioButton('newMedications', {
label: 'Were you prescribed new medications at discharge?',
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No' },
{ id: 'unsure', name: 'Not sure' }
],
orientation: 'horizontal'
});
});
const newMedsSection = medicationSection.addSubform('newMedsSection', {
isVisible: () => medicationSection.radioButton('newMedications')?.value() === 'yes'
});
newMedsSection.addRow(row => {
row.addStarRating('medExplanation', {
label: 'How well were your new medications explained?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
newMedsSection.addRow(row => {
row.addMatrixQuestion('medicationKnowledge', {
label: 'Do you understand the following about your medications?',
rows: [
{ id: 'purpose', label: 'What each medication is for' },
{ id: 'timing', label: 'When to take each medication' },
{ id: 'sideEffects', label: 'Possible side effects' },
{ id: 'interactions', label: 'What to avoid while taking them' }
],
columns: [
{ id: 'no', label: 'No' },
{ id: 'somewhat', label: 'Somewhat' },
{ id: 'yes', label: 'Yes' }
],
fullWidth: true
});
});
// ============================================
// SECTION 4: PAIN MANAGEMENT
// ============================================
const painSection = form.addSubform('painSection', {
title: 'Pain Management',
isVisible: () => medicationSection.radioButton('newMedications')?.value() !== null
});
painSection.addRow(row => {
row.addRadioButton('painAtDischarge', {
label: 'Did you have pain when leaving the hospital?',
options: [
{ id: 'none', name: 'No pain' },
{ id: 'mild', name: 'Mild pain' },
{ id: 'moderate', name: 'Moderate pain' },
{ id: 'severe', name: 'Severe pain' }
],
orientation: 'horizontal'
});
});
const painManagementSection = painSection.addSubform('painManagementSection', {
isVisible: () => {
const pain = painSection.radioButton('painAtDischarge')?.value();
return pain !== null && pain !== 'none';
}
});
painManagementSection.addRow(row => {
row.addSlider('painControlConfidence', {
label: 'How confident are you in managing your pain at home?',
min: 1,
max: 10,
step: 1,
showValue: true,
defaultValue: 5
});
});
painManagementSection.addRow(row => {
row.addCheckboxList('painResources', {
label: 'What pain management information did you receive?',
options: [
{ id: 'schedule', name: 'Pain medication schedule' },
{ id: 'alternatives', name: 'Non-medication pain relief options' },
{ id: 'emergency', name: 'When to call for severe pain' },
{ id: 'refills', name: 'How to get refills if needed' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 5: FOLLOW-UP CARE
// ============================================
const followupSection = form.addSubform('followupSection', {
title: 'Follow-Up Care Coordination',
isVisible: () => painSection.radioButton('painAtDischarge')?.value() !== null
});
followupSection.addRow(row => {
row.addThumbRating('appointmentScheduled', {
label: 'Was a follow-up appointment scheduled before you left?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
alignment: 'center'
});
});
followupSection.addRow(row => {
row.addRatingScale('careCoordination', {
label: 'How well was your transition to home care coordinated?',
preset: 'likert-5',
lowLabel: 'Very poorly',
highLabel: 'Very well',
alignment: 'center'
});
});
followupSection.addRow(row => {
row.addCheckboxList('supportServices', {
label: 'Were you connected with needed support services?',
options: [
{ id: 'homeHealth', name: 'Home health care' },
{ id: 'pt', name: 'Physical therapy' },
{ id: 'pharmacy', name: 'Pharmacy services' },
{ id: 'equipment', name: 'Medical equipment' },
{ id: 'none', name: 'No additional services needed' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 6: STAFF COMMUNICATION
// ============================================
const staffSection = form.addSubform('staffSection', {
title: 'Staff Communication',
isVisible: () => followupSection.thumbRating('appointmentScheduled')?.value() !== null
});
staffSection.addRow(row => {
row.addStarRating('nurseExplanation', {
label: 'How well did nursing staff explain your discharge care?',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('doctorExplanation', {
label: 'How well did doctors explain your condition and care?',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
staffSection.addRow(row => {
row.addRadioButton('questionsEncouraged', {
label: 'Did staff encourage you to ask questions?',
options: [
{ id: 'yes', name: 'Yes, and I felt comfortable asking' },
{ id: 'somewhat', name: 'Somewhat, but felt rushed' },
{ id: 'no', name: 'No, I felt I couldn\'t ask questions' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 7: ADDITIONAL FEEDBACK
// ============================================
const feedbackSection = form.addSubform('feedbackSection', {
title: 'Additional Feedback',
isVisible: () => staffSection.starRating('nurseExplanation')?.value() !== null
});
feedbackSection.addRow(row => {
row.addRadioButton('hadProblems', {
label: 'Have you experienced any problems since leaving the hospital?',
options: [
{ id: 'no', name: 'No problems' },
{ id: 'minor', name: 'Minor issues, resolved' },
{ id: 'ongoing', name: 'Ongoing concerns' },
{ id: 'emergency', name: 'Had to seek emergency care' }
],
orientation: 'vertical'
});
});
feedbackSection.addSpacer({ height: '16px' });
feedbackSection.addRow(row => {
row.addTextarea('additionalComments', {
label: () => {
const problems = feedbackSection.radioButton('hadProblems')?.value();
if (problems === 'ongoing' || problems === 'emergency') {
return 'Please describe the problems you experienced:';
}
return 'Any additional comments about your discharge experience?';
},
placeholder: 'Your feedback helps us improve care for future patients...',
rows: 4,
autoExpand: true
});
});
// ============================================
// SECTION 8: SUMMARY
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => feedbackSection.radioButton('hadProblems')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryPanel', {
computedValue: () => {
const readiness = overallReadiness();
const clarity = instructionClarity();
const coordination = followupSection.ratingScale('careCoordination')?.value();
const problems = feedbackSection.radioButton('hadProblems')?.value();
const readinessLabels: Record<string, string> = {
'very-bad': 'Not ready',
'bad': 'Slightly unprepared',
'neutral': 'Somewhat ready',
'good': 'Ready',
'excellent': 'Very ready'
};
let emoji = '🏥';
if (clarity && clarity >= 4 && (readiness === 'good' || readiness === 'excellent')) {
emoji = '✅';
} else if (problems === 'emergency') {
emoji = '🚨';
} else if (problems === 'ongoing') {
emoji = '⚠️';
}
let summary = `${emoji} Discharge Experience Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `🏥 Readiness: ${readiness ? readinessLabels[readiness] || readiness : 'Not rated'}\n`;
summary += `📋 Instruction Clarity: ${clarity ? clarity + '/5' : 'Not rated'}\n`;
summary += `🤝 Care Coordination: ${coordination ? coordination + '/5' : 'Not rated'}\n`;
summary += `📊 Post-discharge: ${problems === 'no' ? 'No problems' : problems === 'minor' ? 'Minor issues' : problems === 'ongoing' ? 'Ongoing concerns' : problems === 'emergency' ? 'Emergency visit required' : 'Not specified'}`;
return summary;
},
customStyles: () => {
const problems = feedbackSection.radioButton('hadProblems')?.value();
const baseStyles = {
padding: '20px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (problems === 'emergency') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
if (problems === 'ongoing') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#dcfce7', borderLeft: '4px solid #22c55e' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => feedbackSection.radioButton('hadProblems')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback',
message: () => {
const problems = feedbackSection.radioButton('hadProblems')?.value();
if (problems === 'emergency' || problems === 'ongoing') {
return 'We\'re sorry to hear about your difficulties. A patient care coordinator will review your feedback and may reach out to ensure you\'re getting the support you need.';
}
return 'Your feedback helps us improve the discharge experience for all patients. We wish you a speedy recovery!';
}
});
}