export function communityNeedsSurvey(form: FormTs) {
// Community Needs Assessment - Government planning and resident input
// Demonstrates: MatrixQuestion, Slider, StarRating, RadioButton, CheckboxList, EmojiRating, SuggestionChips, conditional visibility, dynamic styling, computed values
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Community Needs Assessment',
computedValue: () => 'Your voice shapes our community. Help us understand your priorities and improve local services.',
customStyles: {
backgroundColor: '#1e40af',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Resident Information
// ============================================
const residentSection = form.addSubform('resident', {
title: 'About You'
});
residentSection.addRow(row => {
row.addDropdown('neighborhood', {
label: 'Which neighborhood or district do you live in?',
options: [
{ id: 'downtown', name: 'Downtown/City Center' },
{ id: 'north', name: 'North District' },
{ id: 'south', name: 'South District' },
{ id: 'east', name: 'East District' },
{ id: 'west', name: 'West District' },
{ id: 'suburban', name: 'Suburban Area' },
{ id: 'rural', name: 'Rural/Outlying Area' }
],
isRequired: true,
placeholder: 'Select your area...'
}, '1fr');
row.addDropdown('residencyLength', {
label: 'How long have you lived in our community?',
options: [
{ id: 'less-1', name: 'Less than 1 year' },
{ id: '1-3', name: '1-3 years' },
{ id: '3-5', name: '3-5 years' },
{ id: '5-10', name: '5-10 years' },
{ id: 'more-10', name: 'More than 10 years' },
{ id: 'lifetime', name: 'Lifetime resident' }
],
isRequired: true,
placeholder: 'Select duration...'
}, '1fr');
});
residentSection.addRow(row => {
row.addCheckboxList('householdType', {
label: 'Which best describes your household? (Select all that apply)',
options: [
{ id: 'children', name: 'Household with children under 18' },
{ id: 'seniors', name: 'Household with seniors 65+' },
{ id: 'disability', name: 'Household member with disability' },
{ id: 'renter', name: 'Renter' },
{ id: 'homeowner', name: 'Homeowner' },
{ id: 'business', name: 'Business owner in community' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 2: Quality of Life
// ============================================
const qualitySection = form.addSubform('quality', {
title: 'Quality of Life',
customStyles: () => {
const satisfaction = qualitySection.emojiRating('overallSatisfaction')?.value();
if (satisfaction === 'excellent' || satisfaction === 'good') {
return { backgroundColor: '#ecfdf5', padding: '16px', borderRadius: '8px' };
}
if (satisfaction === 'bad' || satisfaction === 'very-bad') {
return { backgroundColor: '#fef2f2', padding: '16px', borderRadius: '8px' };
}
return { padding: '16px', borderRadius: '8px', border: '1px dashed #e5e7eb' };
}
});
qualitySection.addRow(row => {
row.addEmojiRating('overallSatisfaction', {
label: 'Overall, how satisfied are you with the quality of life in our community?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
qualitySection.addRow(row => {
row.addSlider('yearsRemaining', {
label: 'How many more years do you plan to live in this community?',
min: 0,
max: 20,
step: 1,
showValue: true,
unit: ' years',
defaultValue: 10,
isVisible: () => qualitySection.emojiRating('overallSatisfaction')?.value() !== null
});
});
// ============================================
// SECTION 3: Municipal Services Assessment (Matrix)
// ============================================
const servicesSection = form.addSubform('services', {
title: 'Municipal Services Assessment'
});
servicesSection.addRow(row => {
row.addTextPanel('servicesInstructions', {
computedValue: () => 'Rate your satisfaction with each municipal service based on your experience.',
customStyles: {
backgroundColor: '#eff6ff',
padding: '12px 16px',
borderRadius: '8px',
borderLeft: '4px solid #3b82f6',
fontSize: '14px'
}
});
});
servicesSection.addRow(row => {
row.addMatrixQuestion('serviceSatisfaction', {
label: 'Service Satisfaction',
rows: [
{ id: 'roads', label: 'Roads & Streets', description: 'Maintenance, potholes, snow removal', isRequired: true },
{ id: 'water', label: 'Water & Sewer', description: 'Quality, reliability, billing', isRequired: true },
{ id: 'trash', label: 'Waste Collection', description: 'Pickup, recycling, bulk items', isRequired: true },
{ id: 'parks', label: 'Parks & Recreation', description: 'Facilities, programs, maintenance', isRequired: true },
{ id: 'police', label: 'Police Services', description: 'Response time, visibility, community relations', isRequired: true },
{ id: 'fire', label: 'Fire & Emergency', description: 'Response, prevention, education', isRequired: true },
{ id: 'library', label: 'Library Services', description: 'Hours, resources, programs', isRequired: true },
{ id: 'permits', label: 'Permits & Licensing', description: 'Process, wait times, staff helpfulness', isRequired: true }
],
columns: [
{ id: 'na', label: 'N/A' },
{ 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: Priority Needs
// ============================================
const prioritySection = form.addSubform('priority', {
title: 'Community Priorities'
});
prioritySection.addRow(row => {
row.addTextPanel('priorityInstructions', {
computedValue: () => 'Select the areas that need the MOST attention and improvement in our community.',
customStyles: {
backgroundColor: '#fef3c7',
padding: '12px 16px',
borderRadius: '8px',
borderLeft: '4px solid #f59e0b',
fontSize: '14px'
}
});
});
prioritySection.addRow(row => {
row.addSuggestionChips('topPriorities', {
label: 'Select your TOP 3 priority areas:',
suggestions: [
{ id: 'affordable-housing', name: 'Affordable Housing' },
{ id: 'job-growth', name: 'Job Growth & Economy' },
{ id: 'public-safety', name: 'Public Safety' },
{ id: 'road-repair', name: 'Road Repair' },
{ id: 'public-transit', name: 'Public Transportation' },
{ id: 'schools', name: 'Schools & Education' },
{ id: 'healthcare', name: 'Healthcare Access' },
{ id: 'environment', name: 'Environment & Sustainability' },
{ id: 'recreation', name: 'Recreation & Parks' },
{ id: 'senior-services', name: 'Senior Services' },
{ id: 'youth-programs', name: 'Youth Programs' },
{ id: 'internet', name: 'Broadband/Internet' }
],
min: 1,
max: 3,
alignment: 'center'
});
});
// ============================================
// SECTION 5: Infrastructure Needs (Matrix)
// ============================================
const infrastructureSection = form.addSubform('infrastructure', {
title: 'Infrastructure Assessment'
});
infrastructureSection.addRow(row => {
row.addMatrixQuestion('infrastructureCondition', {
label: 'Rate the current condition of each infrastructure element:',
rows: [
{ id: 'sidewalks', label: 'Sidewalks & Pedestrian Paths', isRequired: true },
{ id: 'streetlights', label: 'Street Lighting', isRequired: true },
{ id: 'drainage', label: 'Storm Drainage', isRequired: true },
{ id: 'bike-lanes', label: 'Bike Lanes & Trails', isRequired: true },
{ id: 'bridges', label: 'Bridges & Overpasses', isRequired: true },
{ id: 'public-buildings', label: 'Public Buildings', isRequired: true }
],
columns: [
{ id: 'dk', label: "Don't Know" },
{ id: 'poor', label: 'Poor' },
{ id: 'needs-work', label: 'Needs Work' },
{ id: 'acceptable', label: 'Acceptable' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 6: Safety & Security
// ============================================
const safetySection = form.addSubform('safety', {
title: 'Safety & Security'
});
safetySection.addRow(row => {
row.addStarRating('safetySense', {
label: 'How safe do you feel in your neighborhood?',
maxStars: 5,
size: 'lg',
alignment: 'center'
});
});
safetySection.addRow(row => {
row.addCheckboxList('safetyConcerns', {
label: 'What are your primary safety concerns? (Select all that apply)',
options: [
{ id: 'property-crime', name: 'Property crime (theft, vandalism)' },
{ id: 'violent-crime', name: 'Violent crime' },
{ id: 'traffic', name: 'Traffic safety' },
{ id: 'pedestrian', name: 'Pedestrian safety' },
{ id: 'drugs', name: 'Drug activity' },
{ id: 'lighting', name: 'Poor lighting' },
{ id: 'emergency-response', name: 'Slow emergency response' },
{ id: 'none', name: 'No significant concerns' }
],
orientation: 'vertical',
isVisible: () => (safetySection.starRating('safetySense')?.value() ?? 5) <= 3
});
});
// ============================================
// SECTION 7: Communication & Engagement
// ============================================
const engagementSection = form.addSubform('engagement', {
title: 'Communication & Engagement'
});
engagementSection.addRow(row => {
row.addRatingScale('informedRating', {
label: 'How well-informed do you feel about local government decisions and projects?',
preset: 'likert-5',
lowLabel: 'Not informed at all',
highLabel: 'Very well informed',
alignment: 'center'
});
});
engagementSection.addRow(row => {
row.addCheckboxList('preferredChannels', {
label: 'How would you prefer to receive information from local government?',
options: [
{ id: 'email', name: 'Email newsletter' },
{ id: 'website', name: 'Municipal website' },
{ id: 'social', name: 'Social media' },
{ id: 'mail', name: 'Mailed notices' },
{ id: 'newspaper', name: 'Local newspaper' },
{ id: 'meetings', name: 'Public meetings' },
{ id: 'app', name: 'Mobile app' },
{ id: 'radio', name: 'Local radio/TV' }
],
orientation: 'vertical'
});
});
engagementSection.addRow(row => {
row.addThumbRating('attendMeetings', {
label: 'Would you be interested in attending more public meetings if they were more accessible?',
size: 'lg',
showLabels: true,
upLabel: 'Yes, I would attend',
downLabel: 'Probably not',
alignment: 'center'
});
});
// ============================================
// SECTION 8: Open Feedback
// ============================================
const feedbackSection = form.addSubform('feedback', {
title: 'Your Ideas & Suggestions'
});
feedbackSection.addRow(row => {
row.addRadioButton('additionalFeedbackType', {
label: 'Would you like to share additional feedback?',
options: [
{ id: 'yes', name: 'Yes, I have suggestions' },
{ id: 'no', name: 'No, I have shared enough' }
],
orientation: 'horizontal'
});
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('improvementIdeas', {
label: 'What ONE thing would most improve our community?',
placeholder: 'Share your idea for making our community better...',
rows: 3,
autoExpand: true,
isVisible: () => feedbackSection.radioButton('additionalFeedbackType')?.value() === 'yes'
});
});
feedbackSection.addRow(row => {
row.addTextarea('additionalComments', {
label: 'Any other comments or concerns you would like to share?',
placeholder: 'We are listening...',
rows: 3,
autoExpand: true,
isVisible: () => feedbackSection.radioButton('additionalFeedbackType')?.value() === 'yes'
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Assessment Summary',
isVisible: () => qualitySection.emojiRating('overallSatisfaction')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const neighborhood = residentSection.dropdown('neighborhood')?.value();
const satisfaction = qualitySection.emojiRating('overallSatisfaction')?.value();
const priorities = prioritySection.suggestionChips('topPriorities')?.value() || [];
const safety = safetySection.starRating('safetySense')?.value();
const informed = engagementSection.ratingScale('informedRating')?.value();
if (!satisfaction) return '';
const neighborhoodLabels: Record<string, string> = {
'downtown': 'Downtown',
'north': 'North District',
'south': 'South District',
'east': 'East District',
'west': 'West District',
'suburban': 'Suburban',
'rural': 'Rural'
};
const satisfactionLabels: Record<string, string> = {
'very-bad': 'Very Dissatisfied',
'bad': 'Dissatisfied',
'neutral': 'Neutral',
'good': 'Satisfied',
'excellent': 'Very Satisfied'
};
let summary = `Community Needs Assessment Summary\n`;
summary += `${'═'.repeat(36)}\n\n`;
if (neighborhood) {
summary += `Area: ${neighborhoodLabels[neighborhood] || neighborhood}\n`;
}
summary += `Life Satisfaction: ${satisfactionLabels[satisfaction] || satisfaction}\n`;
if (safety !== null && safety !== undefined) {
summary += `Safety Rating: ${safety}/5 stars\n`;
}
if (informed !== null && informed !== undefined) {
summary += `Informed Level: ${informed}/5\n`;
}
if (priorities.length > 0) {
summary += `\nTop Priorities: ${priorities.length} selected\n`;
}
return summary;
},
customStyles: () => {
const satisfaction = qualitySection.emojiRating('overallSatisfaction')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (satisfaction === 'excellent' || satisfaction === 'good') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (satisfaction === 'bad' || satisfaction === 'very-bad') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
} else {
return { ...baseStyles, backgroundColor: '#f3f4f6', borderLeft: '4px solid #3b82f6' };
}
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Assessment',
isVisible: () => qualitySection.emojiRating('overallSatisfaction')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Input!',
message: 'Your feedback is invaluable for shaping our community. The results of this assessment will be shared publicly and used to guide planning decisions. Stay engaged!'
});
}