export function realEstateAgentFeedbackForm(form: FormTs) {
// Real Estate Agent Review Form - Comprehensive agent performance feedback
// Demonstrates: RadioButton, MatrixQuestion, StarRating, RatingScale, Slider, conditional sections
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Agent Performance Review',
computedValue: () => 'Your feedback helps us maintain the highest standards of real estate service.',
customStyles: {
background: 'linear-gradient(135deg, #1e3a5f 0%, #2563eb 100%)',
color: 'white',
padding: '28px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Transaction Details
// ============================================
const transactionSection = form.addSubform('transaction', {
title: 'Transaction Details'
});
transactionSection.addRow(row => {
row.addRadioButton('transactionType', {
label: 'What type of transaction did you complete?',
options: [
{ id: 'buyer', name: 'I was buying a property' },
{ id: 'seller', name: 'I was selling a property' },
{ id: 'both', name: 'Both buying and selling' },
{ id: 'rental', name: 'Rental transaction' }
],
orientation: 'vertical',
isRequired: true
});
});
transactionSection.addRow(row => {
row.addDropdown('propertyType', {
label: 'Property type',
options: [
{ id: 'single-family', name: 'Single Family Home' },
{ id: 'condo', name: 'Condo/Apartment' },
{ id: 'townhouse', name: 'Townhouse' },
{ id: 'multi-family', name: 'Multi-Family' },
{ id: 'land', name: 'Land/Lot' },
{ id: 'commercial', name: 'Commercial' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select property type'
}, '50%');
row.addRadioButton('transactionOutcome', {
label: 'Transaction outcome',
options: [
{ id: 'closed', name: 'Successfully closed' },
{ id: 'cancelled', name: 'Did not complete' }
],
orientation: 'horizontal'
}, '50%');
});
// ============================================
// SECTION 2: Communication & Responsiveness
// ============================================
const communicationSection = form.addSubform('communication', {
title: 'Communication & Responsiveness',
isVisible: () => transactionSection.radioButton('transactionType')?.value() !== null,
customStyles: { backgroundColor: '#eff6ff', padding: '16px', borderRadius: '8px' }
});
communicationSection.addRow(row => {
row.addMatrixQuestion('commRatings', {
label: 'Please rate your agent\'s communication:',
rows: [
{ id: 'response-time', label: 'Response Time', isRequired: true },
{ id: 'availability', label: 'Availability', isRequired: true },
{ id: 'updates', label: 'Proactive Updates', isRequired: true },
{ id: 'listening', label: 'Listening Skills', isRequired: true },
{ id: 'clarity', label: 'Clear Explanations', isRequired: false }
],
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
});
});
communicationSection.addSpacer();
communicationSection.addRow(row => {
row.addRadioButton('preferredContact', {
label: 'How did you primarily communicate with your agent?',
options: [
{ id: 'phone', name: 'Phone calls' },
{ id: 'text', name: 'Text messages' },
{ id: 'email', name: 'Email' },
{ id: 'in-person', name: 'In-person meetings' },
{ id: 'mixed', name: 'Mix of all' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 3: Expertise & Knowledge
// ============================================
const expertiseSection = form.addSubform('expertise', {
title: 'Market Knowledge & Expertise',
isVisible: () => communicationSection.matrixQuestion('commRatings')?.areAllRequiredRowsAnswered() ?? false
});
expertiseSection.addRow(row => {
row.addStarRating('marketKnowledge', {
label: 'Market knowledge',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
row.addStarRating('neighborhoodExpertise', {
label: 'Neighborhood expertise',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
});
expertiseSection.addRow(row => {
row.addStarRating('pricingAdvice', {
label: () => {
const type = transactionSection.radioButton('transactionType')?.value();
if (type === 'seller' || type === 'both') return 'Pricing strategy advice';
return 'Price negotiation skills';
},
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
row.addStarRating('paperworkHandling', {
label: 'Paperwork & process handling',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
});
// ============================================
// SECTION 4: Buyer-Specific Questions
// ============================================
const buyerSection = form.addSubform('buyerExperience', {
title: 'Your Buying Experience',
isVisible: () => {
const type = transactionSection.radioButton('transactionType')?.value();
const expertise = expertiseSection.starRating('marketKnowledge')?.value();
return (type === 'buyer' || type === 'both') && expertise !== null;
},
customStyles: { backgroundColor: '#f0fdf4', padding: '16px', borderRadius: '8px' }
});
buyerSection.addRow(row => {
row.addStarRating('propertySelection', {
label: 'Property options presented',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
row.addStarRating('showingExperience', {
label: 'Property showing experience',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
});
buyerSection.addRow(row => {
row.addThumbRating('foundRightProperty', {
label: 'Did your agent help you find the right property?',
showLabels: true,
upLabel: 'Yes, perfect match!',
downLabel: 'Not quite',
alignment: 'center'
});
});
// ============================================
// SECTION 5: Seller-Specific Questions
// ============================================
const sellerSection = form.addSubform('sellerExperience', {
title: 'Your Selling Experience',
isVisible: () => {
const type = transactionSection.radioButton('transactionType')?.value();
const expertise = expertiseSection.starRating('marketKnowledge')?.value();
return (type === 'seller' || type === 'both') && expertise !== null;
},
customStyles: { backgroundColor: '#fefce8', padding: '16px', borderRadius: '8px' }
});
sellerSection.addRow(row => {
row.addStarRating('marketingEffort', {
label: 'Marketing & exposure',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
row.addStarRating('photoQuality', {
label: 'Photography & presentation',
maxStars: 5,
size: 'lg',
alignment: 'center',
showCounter: true
}, '50%');
});
sellerSection.addRow(row => {
row.addRadioButton('pricingAccuracy', {
label: 'How accurate was the initial listing price recommendation?',
options: [
{ id: 'spot-on', name: 'Spot on - sold near asking' },
{ id: 'slightly-high', name: 'Slightly high - needed adjustment' },
{ id: 'slightly-low', name: 'Underpriced - sold above asking' },
{ id: 'way-off', name: 'Way off the mark' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 6: Negotiation & Closing
// ============================================
const negotiationSection = form.addSubform('negotiation', {
title: 'Negotiation & Closing',
isVisible: () => {
const type = transactionSection.radioButton('transactionType')?.value();
const buyerVisible = type === 'buyer' && buyerSection.thumbRating('foundRightProperty')?.value() !== null;
const sellerVisible = type === 'seller' && sellerSection.radioButton('pricingAccuracy')?.value() !== null;
const bothVisible = type === 'both' && (buyerSection.thumbRating('foundRightProperty')?.value() !== null || sellerSection.radioButton('pricingAccuracy')?.value() !== null);
const rentalVisible = type === 'rental' && expertiseSection.starRating('marketKnowledge')?.value() !== null;
return buyerVisible || sellerVisible || bothVisible || rentalVisible;
}
});
negotiationSection.addRow(row => {
row.addSlider('negotiationSkill', {
label: 'How effective was your agent in negotiations?',
min: 0,
max: 100,
step: 10,
defaultValue: 50,
showValue: true,
unit: '%'
});
});
negotiationSection.addRow(row => {
row.addRadioButton('closingProcess', {
label: 'How smooth was the closing process?',
options: [
{ id: 'seamless', name: 'Seamless - no issues' },
{ id: 'minor-hiccups', name: 'Minor hiccups handled well' },
{ id: 'some-issues', name: 'Some stressful moments' },
{ id: 'difficult', name: 'Difficult process' }
],
orientation: 'vertical'
});
});
// ============================================
// SECTION 7: Overall Experience
// ============================================
const overallSection = form.addSubform('overall', {
title: 'Overall Experience',
isVisible: () => negotiationSection.radioButton('closingProcess')?.value() !== null
});
overallSection.addRow(row => {
row.addRatingScale('npsScore', {
label: 'How likely are you to recommend this agent to friends and family?',
preset: 'nps',
showCategoryLabel: true,
showSegmentColors: true,
showConfettiOnPromoter: true,
isRequired: true
});
});
overallSection.addSpacer();
overallSection.addRow(row => {
row.addSuggestionChips('agentStrengths', {
label: 'What were your agent\'s greatest strengths?',
suggestions: [
{ id: 'responsive', name: 'Responsive' },
{ id: 'knowledgeable', name: 'Knowledgeable' },
{ id: 'patient', name: 'Patient' },
{ id: 'negotiator', name: 'Great negotiator' },
{ id: 'professional', name: 'Professional' },
{ id: 'local-expert', name: 'Local expert' },
{ id: 'honest', name: 'Honest & transparent' },
{ id: 'organized', name: 'Well organized' }
],
max: 4,
alignment: 'center'
});
});
overallSection.addSpacer();
overallSection.addRow(row => {
row.addTextarea('openFeedback', {
label: () => {
const category = overallSection.ratingScale('npsScore')?.npsCategory();
if (category === 'promoter') return 'What made your experience exceptional?';
if (category === 'passive') return 'What would have made this a 9 or 10?';
return 'What could have been done better?';
},
placeholder: 'Share your thoughts...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 8: Testimonial Permission
// ============================================
const testimonialSection = form.addSubform('testimonial', {
title: 'Share Your Experience',
isVisible: () => {
const category = overallSection.ratingScale('npsScore')?.npsCategory();
return category === 'promoter';
},
customStyles: { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' }
});
testimonialSection.addRow(row => {
row.addCheckbox('testimonialConsent', {
label: 'You may use my feedback as a testimonial for this agent'
});
});
testimonialSection.addRow(row => {
row.addTextbox('clientName', {
label: 'Your name (for testimonial attribution)',
placeholder: 'First name and last initial',
isVisible: () => testimonialSection.checkbox('testimonialConsent')?.value() === true
});
});
// ============================================
// SECTION 9: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Review Summary',
isVisible: () => overallSection.ratingScale('npsScore')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const type = transactionSection.radioButton('transactionType')?.value();
const outcome = transactionSection.radioButton('transactionOutcome')?.value();
const market = expertiseSection.starRating('marketKnowledge')?.value();
const neighborhood = expertiseSection.starRating('neighborhoodExpertise')?.value();
const negotiation = negotiationSection.slider('negotiationSkill')?.value();
const closing = negotiationSection.radioButton('closingProcess')?.value();
const nps = overallSection.ratingScale('npsScore')?.value();
const category = overallSection.ratingScale('npsScore')?.npsCategory();
const strengths = overallSection.suggestionChips('agentStrengths')?.value() || [];
if (!type) return '';
const typeLabels: Record<string, string> = {
'buyer': 'Buyer',
'seller': 'Seller',
'both': 'Buyer & Seller',
'rental': 'Rental'
};
let summary = 'Agent Review Summary\n';
summary += `${'═'.repeat(25)}\n\n`;
summary += `Transaction: ${typeLabels[type] || type}\n`;
summary += `Outcome: ${outcome === 'closed' ? 'Successfully closed' : 'Did not complete'}\n\n`;
if (market) summary += `Market Knowledge: ${'★'.repeat(market)}${'☆'.repeat(5 - market)}\n`;
if (neighborhood) summary += `Neighborhood: ${'★'.repeat(neighborhood)}${'☆'.repeat(5 - neighborhood)}\n`;
if (negotiation !== null && negotiation !== undefined) summary += `Negotiation: ${negotiation}%\n`;
if (closing) {
const closingLabels: Record<string, string> = {
'seamless': 'Seamless',
'minor-hiccups': 'Minor hiccups',
'some-issues': 'Some issues',
'difficult': 'Difficult'
};
summary += `Closing: ${closingLabels[closing]}\n`;
}
if (strengths.length > 0) {
summary += `\nStrengths: ${strengths.join(', ')}\n`;
}
if (nps !== null && nps !== undefined) {
summary += `\nNPS: ${nps}/10 (${category?.charAt(0).toUpperCase()}${category?.slice(1)})\n`;
}
return summary;
},
customStyles: () => {
const category = overallSection.ratingScale('npsScore')?.npsCategory();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (category === 'promoter') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (category === 'passive') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
} else if (category === 'detractor') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#eff6ff', borderLeft: '4px solid #2563eb' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Review',
isVisible: () => overallSection.ratingScale('npsScore')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Review!',
message: 'Your feedback helps us maintain the highest standards of real estate service and helps other clients find great agents.'
});
}