export function infrastructureFeedbackSurvey(form: FormTs) {
// Infrastructure & Facilities Rating - Public infrastructure feedback for local government
// Demonstrates: MatrixQuestion, RatingScale, StarRating, Slider, Dropdown, CheckboxList, conditional visibility
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Infrastructure & Facilities Feedback',
computedValue: () => 'Help us improve our community by rating local infrastructure and facilities. Your feedback guides our improvement priorities.',
customStyles: {
backgroundColor: '#0369a1',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Infrastructure Type Selection
// ============================================
const typeSection = form.addSubform('infrastructureType', {
title: 'Select Infrastructure Type'
});
typeSection.addRow(row => {
row.addDropdown('category', {
label: 'What type of infrastructure would you like to provide feedback on?',
options: [
{ id: 'roads', name: 'Roads & Streets' },
{ id: 'sidewalks', name: 'Sidewalks & Pathways' },
{ id: 'parks', name: 'Parks & Recreation Areas' },
{ id: 'buildings', name: 'Public Buildings' },
{ id: 'utilities', name: 'Utilities (Water/Sewer/Electric)' },
{ id: 'lighting', name: 'Street Lighting' },
{ id: 'transit', name: 'Public Transit Facilities' },
{ id: 'stormwater', name: 'Stormwater & Drainage' }
],
placeholder: 'Select a category...',
isRequired: true
});
});
typeSection.addRow(row => {
row.addTextbox('location', {
label: 'Specific location or address (optional)',
placeholder: 'e.g., Main Street between 1st and 2nd Ave',
maxLength: 200
});
});
typeSection.addRow(row => {
row.addRadioButton('usageFrequency', {
label: 'How often do you use this infrastructure?',
options: [
{ id: 'daily', name: 'Daily' },
{ id: 'weekly', name: 'Weekly' },
{ id: 'monthly', name: 'Monthly' },
{ id: 'rarely', name: 'Rarely' }
],
orientation: 'horizontal',
isVisible: () => typeSection.dropdown('category')?.value() !== null
});
});
// ============================================
// SECTION 2: Condition Assessment
// ============================================
const conditionSection = form.addSubform('conditionAssessment', {
title: () => {
const category = typeSection.dropdown('category')?.value();
const categoryNames: Record<string, string> = {
'roads': 'Roads & Streets',
'sidewalks': 'Sidewalks & Pathways',
'parks': 'Parks & Recreation',
'buildings': 'Public Buildings',
'utilities': 'Utilities',
'lighting': 'Street Lighting',
'transit': 'Transit Facilities',
'stormwater': 'Stormwater Systems'
};
return `${categoryNames[category ?? ''] || 'Infrastructure'} Condition Assessment`;
},
isVisible: () => typeSection.dropdown('category')?.value() !== null
});
// Roads-specific matrix
conditionSection.addRow(row => {
row.addMatrixQuestion('roadConditions', {
label: 'Rate the condition of road infrastructure:',
rows: [
{ id: 'surface', label: 'Road surface quality', isRequired: true },
{ id: 'potholes', label: 'Pothole prevalence', isRequired: true },
{ id: 'markings', label: 'Lane markings visibility', isRequired: false },
{ id: 'signage', label: 'Traffic signage', isRequired: false },
{ id: 'drainage', label: 'Road drainage', isRequired: false }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true,
isVisible: () => typeSection.dropdown('category')?.value() === 'roads'
});
});
// Parks-specific matrix
conditionSection.addRow(row => {
row.addMatrixQuestion('parkConditions', {
label: 'Rate the condition of park facilities:',
rows: [
{ id: 'grounds', label: 'Grounds maintenance', isRequired: true },
{ id: 'equipment', label: 'Playground equipment', isRequired: true },
{ id: 'restrooms', label: 'Restroom facilities', isRequired: false },
{ id: 'seating', label: 'Benches and seating', isRequired: false },
{ id: 'trails', label: 'Walking trails', isRequired: false },
{ id: 'lighting', label: 'Park lighting', isRequired: false }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' },
{ id: 'na', label: 'N/A' }
],
striped: true,
fullWidth: true,
isVisible: () => typeSection.dropdown('category')?.value() === 'parks'
});
});
// Generic condition rating for other types
conditionSection.addRow(row => {
row.addMatrixQuestion('generalConditions', {
label: 'Rate the infrastructure condition:',
rows: [
{ id: 'overall', label: 'Overall condition', isRequired: true },
{ id: 'safety', label: 'Safety', isRequired: true },
{ id: 'accessibility', label: 'Accessibility', isRequired: false },
{ id: 'maintenance', label: 'Maintenance level', isRequired: false },
{ id: 'cleanliness', label: 'Cleanliness', isRequired: false }
],
columns: [
{ id: 'poor', label: 'Poor' },
{ id: 'fair', label: 'Fair' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true,
isVisible: () => {
const category = typeSection.dropdown('category')?.value();
return category !== null && category !== 'roads' && category !== 'parks';
}
});
});
// ============================================
// SECTION 3: Overall Rating
// ============================================
const ratingSection = form.addSubform('overallRating', {
title: 'Overall Assessment',
isVisible: () => typeSection.dropdown('category')?.value() !== null
});
ratingSection.addRow(row => {
row.addStarRating('overallCondition', {
label: 'Overall condition rating',
maxStars: 5,
size: 'lg',
alignment: 'center',
showConfettiOnMax: true
});
});
ratingSection.addRow(row => {
row.addEmojiRating('satisfaction', {
label: 'How satisfied are you with this infrastructure?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 4: Issues & Concerns
// ============================================
const issuesSection = form.addSubform('issuesConcerns', {
title: 'Issues & Concerns',
isVisible: () => {
const rating = ratingSection.starRating('overallCondition')?.value();
return rating !== null && rating !== undefined && rating <= 3;
},
customStyles: { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' }
});
issuesSection.addRow(row => {
row.addCheckboxList('issueTypes', {
label: 'What issues have you observed?',
options: [
{ id: 'damage', name: 'Physical damage' },
{ id: 'safety', name: 'Safety hazard' },
{ id: 'accessibility', name: 'Accessibility problems' },
{ id: 'maintenance', name: 'Lack of maintenance' },
{ id: 'lighting', name: 'Inadequate lighting' },
{ id: 'cleanliness', name: 'Cleanliness issues' },
{ id: 'overcrowding', name: 'Overcrowding' },
{ id: 'vandalism', name: 'Vandalism' },
{ id: 'other', name: 'Other' }
],
orientation: 'vertical'
});
});
// Safety hazard priority flag
issuesSection.addRow(row => {
row.addRadioButton('safetyUrgency', {
label: 'Is this a safety hazard requiring urgent attention?',
options: [
{ id: 'critical', name: 'Yes - immediate danger' },
{ id: 'moderate', name: 'Yes - moderate risk' },
{ id: 'low', name: 'Minor concern' },
{ id: 'no', name: 'No safety issue' }
],
orientation: 'vertical',
isVisible: () => {
const issues = issuesSection.checkboxList('issueTypes')?.value() ?? [];
return issues.includes('safety');
}
});
});
issuesSection.addSpacer();
issuesSection.addRow(row => {
row.addTextarea('issueDescription', {
label: () => {
const urgency = issuesSection.radioButton('safetyUrgency')?.value();
if (urgency === 'critical') {
return 'Please describe the safety hazard in detail (this will be prioritized):';
}
return 'Please describe the issues you observed:';
},
placeholder: 'Describe the specific issues, their location, and how they affect usage...',
rows: 4,
isRequired: () => {
const urgency = issuesSection.radioButton('safetyUrgency')?.value();
return urgency === 'critical' || urgency === 'moderate';
}
});
});
// ============================================
// SECTION 5: Improvement Priorities
// ============================================
const prioritySection = form.addSubform('improvementPriorities', {
title: 'Improvement Priorities',
isVisible: () => ratingSection.starRating('overallCondition')?.value() !== null
});
prioritySection.addRow(row => {
row.addSlider('priorityLevel', {
label: 'How important is improving this infrastructure to you?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
showValue: true,
unit: '/ 10'
});
});
prioritySection.addRow(row => {
row.addRatingScale('investmentSupport', {
preset: 'likert-5',
label: 'I would support increased investment in this type of infrastructure',
lowLabel: 'Strongly disagree',
highLabel: 'Strongly agree',
alignment: 'center'
});
});
prioritySection.addSpacer();
prioritySection.addRow(row => {
row.addTextarea('suggestions', {
label: 'What specific improvements would you like to see?',
placeholder: 'Share your suggestions for improving this infrastructure...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 6: Community Impact
// ============================================
const impactSection = form.addSubform('communityImpact', {
title: 'Community Impact',
isVisible: () => ratingSection.emojiRating('satisfaction')?.value() !== null
});
impactSection.addRow(row => {
row.addRatingScale('qualityOfLife', {
preset: 'nps',
label: 'How much does this infrastructure affect your quality of life?',
lowLabel: 'No impact',
highLabel: 'Major impact',
showSegmentColors: false,
alignment: 'center'
});
});
impactSection.addRow(row => {
row.addThumbRating('recommendImprovement', {
label: 'Would you recommend prioritizing improvements here?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
alignment: 'center'
});
});
// ============================================
// SECTION 7: Contact Information
// ============================================
const contactSection = form.addSubform('contactInfo', {
title: 'Contact Information (Optional)',
isVisible: () => typeSection.dropdown('category')?.value() !== null
});
contactSection.addRow(row => {
row.addCheckbox('allowContact', {
label: 'I would like to be notified about improvements to this infrastructure'
});
});
contactSection.addRow(row => {
row.addEmail('email', {
label: 'Email address',
placeholder: 'your@email.com',
isVisible: () => contactSection.checkbox('allowContact')?.value() === true,
isRequired: () => contactSection.checkbox('allowContact')?.value() === true
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => {
const category = typeSection.dropdown('category')?.value();
const rating = ratingSection.starRating('overallCondition')?.value();
return category !== null && rating !== null;
}
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const category = typeSection.dropdown('category')?.value();
const location = typeSection.textbox('location')?.value();
const frequency = typeSection.radioButton('usageFrequency')?.value();
const rating = ratingSection.starRating('overallCondition')?.value();
const satisfaction = ratingSection.emojiRating('satisfaction')?.value();
const priority = prioritySection.slider('priorityLevel')?.value() ?? 5;
const issues = issuesSection.checkboxList('issueTypes')?.value() ?? [];
const urgency = issuesSection.radioButton('safetyUrgency')?.value();
if (!category || rating === null || rating === undefined) return '';
const categoryNames: Record<string, string> = {
'roads': 'Roads & Streets',
'sidewalks': 'Sidewalks & Pathways',
'parks': 'Parks & Recreation',
'buildings': 'Public Buildings',
'utilities': 'Utilities',
'lighting': 'Street Lighting',
'transit': 'Transit Facilities',
'stormwater': 'Stormwater Systems'
};
const satisfactionLabels: Record<string, string> = {
'very-bad': 'Very Dissatisfied',
'bad': 'Dissatisfied',
'neutral': 'Neutral',
'good': 'Satisfied',
'excellent': 'Very Satisfied'
};
let summary = 'Feedback Summary\n';
summary += '═'.repeat(25) + '\n\n';
summary += `Infrastructure: ${categoryNames[category] || category}\n`;
if (location) {
summary += `Location: ${location}\n`;
}
if (frequency) {
summary += `Usage: ${frequency}\n`;
}
summary += `\nCondition: ${'★'.repeat(rating)}${'☆'.repeat(5 - rating)} (${rating}/5)\n`;
if (satisfaction) {
summary += `Satisfaction: ${satisfactionLabels[satisfaction] || satisfaction}\n`;
}
summary += `Priority: ${priority}/10\n`;
if (issues.length > 0) {
summary += `\nIssues reported: ${issues.length}`;
if (urgency === 'critical') {
summary += ' (URGENT SAFETY CONCERN)';
} else if (urgency === 'moderate') {
summary += ' (safety concern)';
}
}
return summary;
},
customStyles: () => {
const urgency = issuesSection.radioButton('safetyUrgency')?.value();
const rating = ratingSection.starRating('overallCondition')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (urgency === 'critical') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #dc2626' };
} else if (rating !== null && rating !== undefined && rating >= 4) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (rating !== null && rating !== undefined && rating <= 2) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#e0e7ff', borderLeft: '4px solid #6366f1' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: () => {
const urgency = issuesSection.radioButton('safetyUrgency')?.value();
if (urgency === 'critical') {
return 'Submit Urgent Report';
}
return 'Submit Feedback';
},
isVisible: () => typeSection.dropdown('category')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your input helps us prioritize infrastructure improvements and allocate resources effectively. If you reported a safety concern, our team will review it promptly.'
});
}