export function buildingInspector(form: FormTs) {
// Building Inspection Feedback Form
// Demonstrates: RatingScale, MatrixQuestion, StarRating, EmojiRating, Dropdown, Datepicker, conditional flows
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Building Inspection Feedback',
computedValue: () => 'Help us improve our inspection services. Your feedback matters.',
customStyles: {
backgroundColor: '#0f766e',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Inspection Details
// ============================================
const inspectionDetails = form.addSubform('inspectionDetails', {
title: 'Inspection Information'
});
inspectionDetails.addRow(row => {
row.addDropdown('inspectionType', {
label: 'Type of Inspection',
options: [
{ id: 'pre-purchase', name: 'Pre-Purchase/Home Inspection' },
{ id: 'electrical', name: 'Electrical Inspection' },
{ id: 'plumbing', name: 'Plumbing Inspection' },
{ id: 'structural', name: 'Structural Inspection' },
{ id: 'foundation', name: 'Foundation Inspection' },
{ id: 'roofing', name: 'Roofing Inspection' },
{ id: 'hvac', name: 'HVAC Inspection' },
{ id: 'fire-safety', name: 'Fire Safety Inspection' },
{ id: 'code-compliance', name: 'Code Compliance' },
{ id: 'final', name: 'Final/Certificate of Occupancy' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select inspection type',
isRequired: true
}, '1fr');
row.addDropdown('propertyType', {
label: 'Property Type',
options: [
{ id: 'residential-single', name: 'Single Family Home' },
{ id: 'residential-multi', name: 'Multi-Family Residential' },
{ id: 'condo', name: 'Condo/Apartment' },
{ id: 'commercial', name: 'Commercial Building' },
{ id: 'industrial', name: 'Industrial Facility' },
{ id: 'new-construction', name: 'New Construction' },
{ id: 'renovation', name: 'Renovation Project' }
],
placeholder: 'Select property type',
isRequired: true
}, '1fr');
});
inspectionDetails.addRow(row => {
row.addDatepicker('inspectionDate', {
label: 'Inspection Date',
isRequired: true
}, '1fr');
row.addDropdown('yourRole', {
label: 'Your Role',
options: [
{ id: 'homeowner', name: 'Homeowner' },
{ id: 'buyer', name: 'Prospective Buyer' },
{ id: 'seller', name: 'Property Seller' },
{ id: 'contractor', name: 'Contractor/Builder' },
{ id: 'agent', name: 'Real Estate Agent' },
{ id: 'property-manager', name: 'Property Manager' }
],
isRequired: true
}, '1fr');
});
// ============================================
// SECTION 2: Overall Experience
// ============================================
const overallSection = form.addSubform('overallSection', {
title: 'Overall Experience',
isVisible: () => inspectionDetails.dropdown('inspectionType')?.value() !== null && inspectionDetails.dropdown('inspectionType')?.value() !== undefined
});
overallSection.addRow(row => {
row.addEmojiRating('overallFeeling', {
label: 'How was your overall inspection experience?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addRatingScale('overallSatisfaction', {
preset: 'satisfaction',
label: 'Overall Satisfaction with the Inspection Service',
alignment: 'center',
isRequired: true
});
});
// ============================================
// SECTION 3: Inspector Performance Matrix
// ============================================
const performanceSection = form.addSubform('performanceSection', {
title: 'Inspector Performance',
isVisible: () => overallSection.ratingScale('overallSatisfaction')?.value() !== null && overallSection.ratingScale('overallSatisfaction')?.value() !== undefined
});
performanceSection.addRow(row => {
row.addMatrixQuestion('inspectorMatrix', {
label: 'Please rate the inspector on the following aspects:',
rows: [
{ id: 'punctuality', label: 'Punctuality', description: 'Arrived on time as scheduled', isRequired: true },
{ id: 'thoroughness', label: 'Thoroughness', description: 'Comprehensive examination of property', isRequired: true },
{ id: 'knowledge', label: 'Technical Knowledge', description: 'Expertise in building codes and systems', isRequired: true },
{ id: 'communication', label: 'Communication', description: 'Clear explanations of findings', isRequired: true },
{ id: 'professionalism', label: 'Professionalism', description: 'Courtesy and professional demeanor', isRequired: true },
{ id: 'report-quality', label: 'Report Quality', description: 'Clear, detailed, and useful documentation', isRequired: true }
],
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: Key Ratings
// ============================================
const ratingsSection = form.addSubform('ratingsSection', {
title: 'Service Quality',
isVisible: () => performanceSection.matrixQuestion('inspectorMatrix')?.areAllRequiredRowsAnswered() === true,
customStyles: { backgroundColor: '#f0fdfa', padding: '20px', borderRadius: '10px' }
});
ratingsSection.addRow(row => {
row.addStarRating('processClarity', {
label: 'Process Clarity',
tooltip: 'How well the inspection process was explained',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'center'
}, '1fr');
row.addStarRating('valueForMoney', {
label: 'Value for Money',
tooltip: 'Worth the cost of the inspection',
maxStars: 5,
size: 'lg',
showCounter: true,
alignment: 'center'
}, '1fr');
});
ratingsSection.addRow(row => {
row.addRatingScale('effortScore', {
preset: 'ces',
label: 'How easy was it to schedule and complete the inspection?',
alignment: 'center',
size: 'md'
});
});
// ============================================
// SECTION 5: Issues (for lower satisfaction)
// ============================================
const issuesSection = form.addSubform('issuesSection', {
title: 'Areas of Concern',
isVisible: () => {
const satisfaction = overallSection.ratingScale('overallSatisfaction')?.value();
return satisfaction !== null && satisfaction !== undefined && satisfaction <= 3;
},
customStyles: { backgroundColor: '#fef2f2', padding: '20px', borderRadius: '10px' }
});
issuesSection.addRow(row => {
row.addCheckboxList('issuesEncountered', {
label: 'What issues did you experience? (Select all that apply)',
options: [
{ id: 'late', name: 'Inspector was late' },
{ id: 'rushed', name: 'Inspection felt rushed' },
{ id: 'incomplete', name: 'Areas were not inspected' },
{ id: 'unclear', name: 'Findings were unclear' },
{ id: 'unprofessional', name: 'Unprofessional behavior' },
{ id: 'unresponsive', name: 'Slow to respond to questions' },
{ id: 'report-delayed', name: 'Report was delayed' },
{ id: 'report-incomplete', name: 'Report was incomplete' },
{ id: 'pricing', name: 'Unexpected fees or pricing issues' }
],
orientation: 'vertical'
});
});
issuesSection.addSpacer({ height: '15px' });
issuesSection.addRow(row => {
row.addTextarea('issueDetails', {
label: 'Please describe the issues in detail:',
placeholder: 'Help us understand what went wrong so we can improve...',
rows: 4,
autoExpand: true,
isVisible: () => (issuesSection.checkboxList('issuesEncountered')?.value()?.length ?? 0) > 0
});
});
// ============================================
// SECTION 6: Positive Feedback (for higher satisfaction)
// ============================================
const positiveSection = form.addSubform('positiveSection', {
title: 'What Impressed You',
isVisible: () => {
const satisfaction = overallSection.ratingScale('overallSatisfaction')?.value();
return satisfaction !== null && satisfaction !== undefined && satisfaction >= 4;
},
customStyles: { backgroundColor: '#f0fdf4', padding: '20px', borderRadius: '10px' }
});
positiveSection.addRow(row => {
row.addCheckboxList('positiveAspects', {
label: 'What did you appreciate most? (Select all that apply)',
options: [
{ id: 'thorough', name: 'Very thorough inspection' },
{ id: 'knowledgeable', name: 'Highly knowledgeable inspector' },
{ id: 'explained', name: 'Excellent explanations' },
{ id: 'patient', name: 'Patient and answered all questions' },
{ id: 'organized', name: 'Well-organized process' },
{ id: 'timely', name: 'On time and efficient' },
{ id: 'helpful-report', name: 'Very helpful report' },
{ id: 'recommendations', name: 'Valuable recommendations' }
],
orientation: 'vertical'
});
});
positiveSection.addRow(row => {
row.addTextarea('positiveComments', {
label: 'What else went well?',
placeholder: 'Share what made this inspection experience great...',
rows: 3,
autoExpand: true,
isVisible: () => (positiveSection.checkboxList('positiveAspects')?.value()?.length ?? 0) > 0
});
});
// ============================================
// SECTION 7: Recommendation
// ============================================
const recommendSection = form.addSubform('recommendSection', {
title: 'Recommendation',
isVisible: () => performanceSection.matrixQuestion('inspectorMatrix')?.areAllRequiredRowsAnswered() === true
});
recommendSection.addRow(row => {
row.addThumbRating('wouldRecommend', {
label: 'Would you recommend this inspector to others?',
showLabels: true,
upLabel: 'Yes, definitely',
downLabel: 'Probably not',
size: 'lg',
alignment: 'center'
});
});
recommendSection.addRow(row => {
row.addThumbRating('wouldUseAgain', {
label: 'Would you use this inspection service again?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
size: 'lg',
alignment: 'center',
isVisible: () => recommendSection.thumbRating('wouldRecommend')?.value() !== null && recommendSection.thumbRating('wouldRecommend')?.value() !== undefined
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => recommendSection.thumbRating('wouldUseAgain')?.value() !== null && recommendSection.thumbRating('wouldUseAgain')?.value() !== undefined
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const inspType = inspectionDetails.dropdown('inspectionType')?.value();
const propType = inspectionDetails.dropdown('propertyType')?.value();
const overall = overallSection.ratingScale('overallSatisfaction')?.value();
const feeling = overallSection.emojiRating('overallFeeling')?.value();
const processClarity = ratingsSection.starRating('processClarity')?.value();
const valueForMoney = ratingsSection.starRating('valueForMoney')?.value();
const recommend = recommendSection.thumbRating('wouldRecommend')?.value();
const useAgain = recommendSection.thumbRating('wouldUseAgain')?.value();
if (!overall) return '';
const inspTypeLabels: Record<string, string> = {
'pre-purchase': 'Pre-Purchase', 'electrical': 'Electrical', 'plumbing': 'Plumbing',
'structural': 'Structural', 'foundation': 'Foundation', 'roofing': 'Roofing',
'hvac': 'HVAC', 'fire-safety': 'Fire Safety', 'code-compliance': 'Code Compliance',
'final': 'Final/CO', 'other': 'Other'
};
const propTypeLabels: Record<string, string> = {
'residential-single': 'Single Family', 'residential-multi': 'Multi-Family',
'condo': 'Condo', 'commercial': 'Commercial', 'industrial': 'Industrial',
'new-construction': 'New Construction', 'renovation': 'Renovation'
};
const feelingEmojis: Record<string, string> = {
'very-bad': '😡', 'bad': '😕', 'neutral': '😐', 'good': '🙂', 'excellent': '😍'
};
let emoji = overall >= 4 ? '🏠' : overall <= 2 ? '🚧' : '📋';
let summary = `${emoji} Inspection Feedback Summary\n`;
summary += `${'═'.repeat(30)}\n\n`;
if (inspType) summary += `📋 Type: ${inspTypeLabels[inspType] || inspType}\n`;
if (propType) summary += `🏢 Property: ${propTypeLabels[propType] || propType}\n`;
summary += `\n`;
summary += `📊 Satisfaction: ${overall}/5\n`;
if (feeling) summary += `${feelingEmojis[feeling] || ''} Experience: ${feeling}\n`;
if (processClarity) summary += `📝 Process Clarity: ${processClarity}/5\n`;
if (valueForMoney) summary += `💰 Value: ${valueForMoney}/5\n`;
summary += `\n`;
summary += `👍 Recommend: ${recommend === 'up' ? 'Yes' : 'No'}\n`;
summary += `🔄 Use Again: ${useAgain === 'up' ? 'Yes' : 'No'}`;
return summary;
},
customStyles: () => {
const recommend = recommendSection.thumbRating('wouldRecommend')?.value();
const useAgain = recommendSection.thumbRating('wouldUseAgain')?.value();
const baseStyles = {
padding: '20px',
borderRadius: '10px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (recommend === 'up' && useAgain === 'up') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #059669' };
} else if (recommend === 'down' || useAgain === 'down') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f1f5f9', borderLeft: '4px solid #64748b' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => recommendSection.thumbRating('wouldUseAgain')?.value() !== null && recommendSection.thumbRating('wouldUseAgain')?.value() !== undefined
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your input helps us maintain high inspection standards and improve our services. We appreciate you taking the time to share your experience.'
});
}