export function realEstateShowingSurvey(form: FormTs) {
// Property Showing Feedback - Real estate buyer feedback after viewings
// Demonstrates: StarRating, Slider, RadioButton, Dropdown, MatrixQuestion, Integer, ThumbRating, Datepicker, PriceDisplay
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Property Showing Feedback',
computedValue: () => 'Thank you for viewing this property. Your feedback helps us find your perfect home.',
customStyles: {
background: 'linear-gradient(135deg, #0891b2 0%, #06b6d4 100%)',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Property Details
// ============================================
const detailsSection = form.addSubform('detailsSection', {
title: 'Property Information'
});
detailsSection.addRow(row => {
row.addTextbox('propertyAddress', {
label: 'Property address',
placeholder: '123 Main Street, City',
isRequired: true
});
});
detailsSection.addRow(row => {
row.addDatepicker('showingDate', {
label: 'Showing date',
isRequired: true
}, '1fr');
row.addDropdown('propertyType', {
label: 'Property type',
options: [
{ id: 'house', name: 'Single-family home' },
{ id: 'condo', name: 'Condo / Apartment' },
{ id: 'townhouse', name: 'Townhouse' },
{ id: 'multi', name: 'Multi-family' },
{ id: 'land', name: 'Land / Lot' },
{ id: 'commercial', name: 'Commercial' }
]
}, '1fr');
});
detailsSection.addRow(row => {
row.addInteger('askingPrice', {
label: 'Asking price ($)',
min: 0,
placeholder: '500000'
}, '1fr');
row.addInteger('bedrooms', {
label: 'Bedrooms',
min: 0,
max: 20,
placeholder: '3'
}, '1fr');
row.addInteger('sqft', {
label: 'Square feet',
min: 0,
placeholder: '2000'
}, '1fr');
});
// ============================================
// SECTION 2: Interest Level
// ============================================
const interestSection = form.addSubform('interestSection', {
title: 'Your Interest Level',
customStyles: () => {
const interest = interestSection.slider('interestLevel')?.value() ?? 5;
if (interest >= 8) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px', border: '2px solid #10b981' };
if (interest <= 3) return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' };
}
});
interestSection.addRow(row => {
row.addSlider('interestLevel', {
label: () => {
const level = interestSection.slider('interestLevel')?.value() ?? 5;
if (level >= 8) return 'How interested are you in this property? (Very Interested!)';
if (level <= 3) return 'How interested are you in this property? (Not a match)';
return 'How interested are you in this property?';
},
min: 1,
max: 10,
defaultValue: 5,
showValue: true,
unit: '/10'
});
});
// High interest follow-up
interestSection.addRow(row => {
row.addRadioButton('nextSteps', {
label: 'What would you like to do next?',
options: [
{ id: 'offer', name: 'Ready to make an offer' },
{ id: 'second', name: 'Schedule a second showing' },
{ id: 'think', name: 'Need time to think' },
{ id: 'compare', name: 'Want to see comparable properties first' }
],
orientation: 'vertical',
isVisible: () => (interestSection.slider('interestLevel')?.value() ?? 0) >= 7
});
});
// Low interest follow-up
interestSection.addRow(row => {
row.addCheckboxList('dealBreakers', {
label: 'What were the main concerns? (select all that apply)',
options: [
{ id: 'price', name: 'Price too high' },
{ id: 'size', name: 'Too small/large' },
{ id: 'layout', name: 'Poor layout' },
{ id: 'condition', name: 'Needs too much work' },
{ id: 'location', name: 'Location not ideal' },
{ id: 'yard', name: 'Yard/outdoor space' },
{ id: 'parking', name: 'Parking issues' },
{ id: 'neighborhood', name: 'Neighborhood concerns' }
],
orientation: 'vertical',
isVisible: () => (interestSection.slider('interestLevel')?.value() ?? 5) <= 4
});
});
// ============================================
// SECTION 3: Property Ratings
// ============================================
const ratingsSection = form.addSubform('ratingsSection', {
title: 'Property Ratings'
});
ratingsSection.addRow(row => {
row.addMatrixQuestion('propertyAspects', {
label: 'Rate these aspects of the property:',
rows: [
{ id: 'location', label: 'Location', isRequired: true },
{ id: 'condition', label: 'Overall condition' },
{ id: 'layout', label: 'Floor plan / Layout' },
{ id: 'size', label: 'Size for your needs' },
{ id: 'natural_light', label: 'Natural light' },
{ id: 'storage', label: 'Storage space' },
{ id: 'outdoor', label: 'Outdoor space' },
{ id: 'parking', label: 'Parking' }
],
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: Price Perception
// ============================================
const priceSection = form.addSubform('priceSection', {
title: 'Price Perception'
});
priceSection.addRow(row => {
row.addRatingScale('priceOpinion', {
preset: 'likert-5',
label: 'The asking price is fair for this property',
lowLabel: 'Strongly Disagree',
highLabel: 'Strongly Agree',
alignment: 'center'
});
});
priceSection.addRow(row => {
row.addInteger('fairPrice', {
label: 'What do you think would be a fair price? ($)',
min: 0,
placeholder: 'Your estimate...'
}, '1fr');
row.addPriceDisplay('priceDifference', {
label: 'Difference from asking',
computedValue: () => {
const asking = detailsSection.integer('askingPrice')?.value();
const fair = priceSection.integer('fairPrice')?.value();
if (asking && fair) return fair - asking;
return null;
},
currency: '$',
prefix: () => {
const asking = detailsSection.integer('askingPrice')?.value();
const fair = priceSection.integer('fairPrice')?.value();
if (asking && fair) {
return fair > asking ? '+' : '';
}
return '';
}
}, '1fr');
});
priceSection.addRow(row => {
row.addInteger('maxBudget', {
label: 'What is your maximum budget for a home? ($)',
min: 0,
placeholder: 'Optional'
});
});
// ============================================
// SECTION 5: Neighborhood
// ============================================
const neighborhoodSection = form.addSubform('neighborhoodSection', {
title: 'Neighborhood & Location'
});
neighborhoodSection.addRow(row => {
row.addStarRating('neighborhoodRating', {
label: 'Overall neighborhood impression',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('commuteRating', {
label: 'Convenience for your commute',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
neighborhoodSection.addRow(row => {
row.addSuggestionChips('neighborhoodPros', {
label: 'What did you like about the neighborhood?',
suggestions: [
{ id: 'quiet', name: 'Quiet/peaceful' },
{ id: 'schools', name: 'Good schools' },
{ id: 'shops', name: 'Near shopping' },
{ id: 'parks', name: 'Parks/recreation' },
{ id: 'transit', name: 'Public transit' },
{ id: 'safe', name: 'Feels safe' },
{ id: 'walkable', name: 'Walkable' },
{ id: 'restaurants', name: 'Dining options' }
],
alignment: 'left'
});
});
// ============================================
// SECTION 6: Agent Feedback
// ============================================
const agentSection = form.addSubform('agentSection', {
title: 'Your Agent'
});
agentSection.addRow(row => {
row.addStarRating('agentKnowledge', {
label: 'Agent\'s knowledge of the property',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
row.addStarRating('agentHelpful', {
label: 'Agent\'s helpfulness',
maxStars: 5,
size: 'md',
alignment: 'center'
}, '1fr');
});
agentSection.addRow(row => {
row.addThumbRating('workWithAgent', {
label: 'Would you continue working with this agent?',
showLabels: true,
upLabel: 'Yes, definitely!',
downLabel: 'Have concerns',
alignment: 'center'
});
});
agentSection.addRow(row => {
row.addTextarea('agentFeedback', {
label: 'Any feedback for your agent?',
placeholder: 'What could they do better, or what did they do well?',
rows: 2,
isVisible: () => agentSection.thumbRating('workWithAgent')?.value() !== null
});
});
// ============================================
// SECTION 7: Competition & Timeline
// ============================================
const timelineSection = form.addSubform('timelineSection', {
title: 'Your Search'
});
timelineSection.addRow(row => {
row.addDropdown('searchTimeline', {
label: 'When are you hoping to buy?',
options: [
{ id: 'asap', name: 'As soon as possible' },
{ id: '1month', name: 'Within 1 month' },
{ id: '3months', name: 'Within 3 months' },
{ id: '6months', name: 'Within 6 months' },
{ id: 'year', name: 'Within a year' },
{ id: 'browsing', name: 'Just browsing' }
]
}, '1fr');
row.addDropdown('propertiesViewed', {
label: 'How many properties have you viewed?',
options: [
{ id: 'first', name: 'This is my first' },
{ id: '2-5', name: '2-5 properties' },
{ id: '6-10', name: '6-10 properties' },
{ id: '10+', name: 'More than 10' }
]
}, '1fr');
});
timelineSection.addRow(row => {
row.addRadioButton('otherViewings', {
label: 'Are you viewing other properties soon?',
options: [
{ id: 'no', name: 'No, focused on this one' },
{ id: 'few', name: 'Yes, a few others' },
{ id: 'many', name: 'Yes, several scheduled' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 8: Additional Comments
// ============================================
const commentsSection = form.addSubform('commentsSection', {
title: 'Additional Thoughts'
});
commentsSection.addRow(row => {
row.addTextarea('likes', {
label: 'What did you like most about this property?',
placeholder: 'Features, rooms, aspects that stood out...',
rows: 2,
autoExpand: true
});
});
commentsSection.addRow(row => {
row.addTextarea('improvements', {
label: 'What would need to change for you to buy this property?',
placeholder: 'Price, repairs, features...',
rows: 2,
autoExpand: true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Showing Summary',
isVisible: () => (interestSection.slider('interestLevel')?.value() ?? 0) > 0
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const interest = interestSection.slider('interestLevel')?.value() ?? 0;
const nextStep = interestSection.radioButton('nextSteps')?.value();
const priceOpinion = priceSection.ratingScale('priceOpinion')?.value();
const neighborhood = neighborhoodSection.starRating('neighborhoodRating')?.value() ?? 0;
const timeline = timelineSection.dropdown('searchTimeline')?.value();
let status = '';
if (interest >= 8) status = 'HOT LEAD';
else if (interest >= 6) status = 'INTERESTED';
else if (interest >= 4) status = 'LUKEWARM';
else status = 'NOT A MATCH';
const nextStepLabels: Record<string, string> = {
'offer': 'Ready to make an offer!',
'second': 'Wants second showing',
'think': 'Needs time to think',
'compare': 'Wants to see comparables'
};
const timelineLabels: Record<string, string> = {
'asap': 'ASAP', '1month': '1 month', '3months': '3 months',
'6months': '6 months', 'year': 'Within a year', 'browsing': 'Just browsing'
};
let summary = `Lead Status: ${status}\n`;
summary += '═'.repeat(25) + '\n\n';
summary += `Interest Level: ${interest}/10\n`;
if (nextStep) {
summary += `Next Step: ${nextStepLabels[nextStep] || nextStep}\n`;
}
if (priceOpinion) {
const priceText = priceOpinion >= 4 ? 'Fair' : priceOpinion === 3 ? 'Neutral' : 'Too High';
summary += `Price Opinion: ${priceText}\n`;
}
summary += `Neighborhood: ${neighborhood > 0 ? '★'.repeat(neighborhood) + '☆'.repeat(5 - neighborhood) : 'Not rated'}\n`;
if (timeline) {
summary += `Timeline: ${timelineLabels[timeline] || timeline}\n`;
}
return summary;
},
customStyles: () => {
const interest = interestSection.slider('interestLevel')?.value() ?? 0;
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (interest >= 8) return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
if (interest >= 6) return { ...baseStyles, backgroundColor: '#dbeafe', borderLeft: '4px solid #3b82f6' };
if (interest >= 4) return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback'
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank you for your feedback!',
message: 'Your insights help us find properties that better match your needs. Your agent will follow up with you shortly.'
});
}