export function homeBuyingReadinessQuiz(form: FormTs) {
form.setTitle(() => '🏠 Are You Ready to Buy a Home?');
// ========== STATE ==========
type CategoryKey = 'financial' | 'credit' | 'savings' | 'stability' | 'knowledge';
const scores = form.state<Record<CategoryKey, number>>({
financial: 0,
credit: 0,
savings: 0,
stability: 0,
knowledge: 0
});
// ========== SCORING FUNCTIONS ==========
const updateScore = (category: CategoryKey, points: number) => {
scores.update(current => ({
...current,
[category]: (current[category] || 0) + points
}));
};
const getTotalScore = () => {
const s = scores();
return (Object.values(s) as number[]).reduce((sum: number, val: number) => sum + val, 0);
};
const getMaxScore = () => 100;
const getScorePercentage = () => Math.round((getTotalScore() / getMaxScore()) * 100);
const getReadinessLevel = (): 'ready' | 'almost' | 'preparing' | 'building' | 'starting' => {
const pct = getScorePercentage();
if (pct >= 80) return 'ready';
if (pct >= 65) return 'almost';
if (pct >= 50) return 'preparing';
if (pct >= 35) return 'building';
return 'starting';
};
const getReadinessLabel = () => {
const level = getReadinessLevel();
const labels = {
ready: '🎉 Ready to Buy!',
almost: '📈 Almost There',
preparing: '🔧 Preparing Well',
building: '🏗️ Building Foundation',
starting: '🌱 Early Stage'
};
return labels[level];
};
const getReadinessDescription = () => {
const level = getReadinessLevel();
const descriptions = {
ready: 'Congratulations! You appear to be in a strong position to buy a home. You have the financial stability, savings, and knowledge to navigate the home buying process.',
almost: 'You\'re very close to being ready. Focus on strengthening your weaker areas, and you should be ready to buy within 3-6 months.',
preparing: 'You\'re making good progress. Keep building your savings and improving your credit. You could be ready in 6-12 months.',
building: 'You\'re laying the groundwork. Focus on the basics: emergency fund, credit improvement, and debt reduction. Plan for 12-18 months.',
starting: 'You\'re early in your home buying journey. Focus on financial fundamentals first: stable income, building credit, and starting to save.'
};
return descriptions[level];
};
const getCategoryScore = (category: CategoryKey) => {
const s = scores();
const maxPerCategory = 20;
return Math.round((s[category] / maxPerCategory) * 100);
};
const getWeakestArea = (): CategoryKey => {
const s = scores();
const entries = Object.entries(s) as [CategoryKey, number][];
const sorted = entries.sort((a, b) => a[1] - b[1]);
return sorted[0]?.[0] || 'savings';
};
const getCategoryLabel = (category: CategoryKey) => {
const labels: Record<CategoryKey, string> = {
financial: 'Income & Debt',
credit: 'Credit Score',
savings: 'Down Payment & Savings',
stability: 'Life Stability',
knowledge: 'Market Knowledge'
};
return labels[category];
};
// ========== COMPLETION SCREEN ==========
form.configureCompletionScreen({
type: 'text',
title: () => `🏠 ${getReadinessLabel()}`,
message: () => `Your home buying readiness score is ${getScorePercentage()}%. ${getReadinessDescription()} Check your email for your personalized action plan.`
});
// ========== PAGES ==========
const pages = form.addPages('quiz-pages', { heightMode: 'current-page' });
// ========== PAGE 1: Financial ==========
const page1 = pages.addPage('financial', { mobileBreakpoint: 500 });
page1.addRow(row => {
row.addTextPanel('header1', {
label: 'Step 1 of 6: Income & Debt',
computedValue: () => 'Let\'s assess your financial foundation',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page1.addSpacer({ height: '24px' });
page1.addRow(row => {
row.addRadioButton('income', {
label: 'How would you describe your income?',
options: [
{ id: 'stable', name: 'Stable salary for 2+ years' },
{ id: 'growing', name: 'Stable with recent growth' },
{ id: 'new', name: 'New job (less than 2 years)' },
{ id: 'variable', name: 'Variable/self-employed' },
{ id: 'unstable', name: 'Currently between jobs or unstable' }
],
orientation: 'vertical',
onValueChange: (v) => {
if (v === 'stable') updateScore('financial', 10);
else if (v === 'growing') updateScore('financial', 10);
else if (v === 'new') updateScore('financial', 6);
else if (v === 'variable') updateScore('financial', 5);
else if (v === 'unstable') updateScore('financial', 1);
}
});
});
page1.addRow(row => {
row.addRadioButton('dti', {
label: 'What\'s your debt-to-income ratio (monthly debt / monthly income)?',
options: [
{ id: 'low', name: 'Under 20% - minimal debt' },
{ id: 'moderate', name: '20-35% - manageable' },
{ id: 'high', name: '36-43% - getting tight' },
{ id: 'very_high', name: 'Over 43% - too much debt' },
{ id: 'unsure', name: 'Not sure' }
],
orientation: 'vertical',
tooltip: 'Lenders prefer DTI under 43%. Include car loans, student loans, credit cards, etc.',
onValueChange: (v) => {
if (v === 'low') updateScore('financial', 10);
else if (v === 'moderate') updateScore('financial', 8);
else if (v === 'high') updateScore('financial', 4);
else if (v === 'very_high') updateScore('financial', 1);
else if (v === 'unsure') updateScore('financial', 3);
}
});
});
// ========== PAGE 2: Credit ==========
const page2 = pages.addPage('credit', { mobileBreakpoint: 500 });
page2.addRow(row => {
row.addTextPanel('header2', {
label: 'Step 2 of 6: Credit Score',
computedValue: () => 'Credit affects your mortgage rate',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page2.addSpacer({ height: '24px' });
page2.addRow(row => {
row.addRadioButton('creditScore', {
label: 'What\'s your credit score?',
options: [
{ id: 'excellent', name: '760+ (Excellent)' },
{ id: 'good', name: '700-759 (Good)' },
{ id: 'fair', name: '650-699 (Fair)' },
{ id: 'poor', name: '600-649 (Poor)' },
{ id: 'bad', name: 'Below 600 (Very Poor)' },
{ id: 'unsure', name: 'I don\'t know my score' }
],
orientation: 'vertical',
onValueChange: (v) => {
if (v === 'excellent') updateScore('credit', 10);
else if (v === 'good') updateScore('credit', 8);
else if (v === 'fair') updateScore('credit', 5);
else if (v === 'poor') updateScore('credit', 3);
else if (v === 'bad') updateScore('credit', 1);
else if (v === 'unsure') updateScore('credit', 2);
}
});
});
page2.addRow(row => {
row.addRadioButton('creditHistory', {
label: 'Any negative credit events in the last 2 years?',
options: [
{ id: 'clean', name: 'No - clean credit history' },
{ id: 'minor', name: 'Minor late payments' },
{ id: 'major', name: 'Collections or charge-offs' },
{ id: 'bankruptcy', name: 'Bankruptcy or foreclosure' }
],
orientation: 'vertical',
onValueChange: (v) => {
if (v === 'clean') updateScore('credit', 10);
else if (v === 'minor') updateScore('credit', 6);
else if (v === 'major') updateScore('credit', 3);
else if (v === 'bankruptcy') updateScore('credit', 1);
}
});
});
// ========== PAGE 3: Savings ==========
const page3 = pages.addPage('savings', { mobileBreakpoint: 500 });
page3.addRow(row => {
row.addTextPanel('header3', {
label: 'Step 3 of 6: Down Payment & Savings',
computedValue: () => 'How much have you saved?',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page3.addSpacer({ height: '24px' });
page3.addRow(row => {
row.addRadioButton('downPayment', {
label: 'How much do you have saved for a down payment?',
options: [
{ id: 'twenty', name: '20%+ of target home price' },
{ id: 'fifteen', name: '10-20% of target price' },
{ id: 'ten', name: '5-10% of target price' },
{ id: 'low', name: '3-5% of target price' },
{ id: 'none', name: 'Less than 3%' }
],
orientation: 'vertical',
tooltip: '20% avoids PMI. 3-5% minimum for most loans.',
onValueChange: (v) => {
if (v === 'twenty') updateScore('savings', 10);
else if (v === 'fifteen') updateScore('savings', 8);
else if (v === 'ten') updateScore('savings', 6);
else if (v === 'low') updateScore('savings', 4);
else if (v === 'none') updateScore('savings', 1);
}
});
});
page3.addRow(row => {
row.addRadioButton('emergency', {
label: 'Do you have an emergency fund beyond the down payment?',
options: [
{ id: 'sixmonths', name: '6+ months of expenses' },
{ id: 'threemonths', name: '3-6 months of expenses' },
{ id: 'some', name: '1-3 months of expenses' },
{ id: 'minimal', name: 'Less than 1 month' }
],
orientation: 'vertical',
tooltip: 'Lenders want to see reserves after closing. Homes have unexpected costs.',
onValueChange: (v) => {
if (v === 'sixmonths') updateScore('savings', 10);
else if (v === 'threemonths') updateScore('savings', 7);
else if (v === 'some') updateScore('savings', 4);
else if (v === 'minimal') updateScore('savings', 1);
}
});
});
// ========== PAGE 4: Stability ==========
const page4 = pages.addPage('stability', { mobileBreakpoint: 500 });
page4.addRow(row => {
row.addTextPanel('header4', {
label: 'Step 4 of 6: Life Stability',
computedValue: () => 'Is this the right time in your life?',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page4.addSpacer({ height: '24px' });
page4.addRow(row => {
row.addRadioButton('stayDuration', {
label: 'How long do you plan to stay in this home?',
options: [
{ id: 'longtime', name: '7+ years' },
{ id: 'medium', name: '5-7 years' },
{ id: 'short', name: '3-5 years' },
{ id: 'unsure', name: 'Less than 3 years or unsure' }
],
orientation: 'vertical',
tooltip: 'Generally need 5+ years to break even on buying vs renting.',
onValueChange: (v) => {
if (v === 'longtime') updateScore('stability', 10);
else if (v === 'medium') updateScore('stability', 8);
else if (v === 'short') updateScore('stability', 4);
else if (v === 'unsure') updateScore('stability', 2);
}
});
});
page4.addRow(row => {
row.addSuggestionChips('lifeChanges', {
label: 'Any major life changes expected in 1-2 years?',
suggestions: [
{ id: 'none', name: '✅ None expected' },
{ id: 'job', name: '💼 Job change/move' },
{ id: 'family', name: '👶 Growing family' },
{ id: 'marriage', name: '💍 Marriage/divorce' },
{ id: 'retire', name: '🏖️ Retirement' }
],
onValueChange: (v) => {
const picks = v || [];
if (picks.includes('none')) updateScore('stability', 10);
else if (picks.includes('family')) updateScore('stability', 6);
else if (picks.includes('marriage')) updateScore('stability', 4);
else if (picks.includes('job')) updateScore('stability', 2);
else if (picks.includes('retire')) updateScore('stability', 5);
}
});
});
// ========== PAGE 5: Knowledge ==========
const page5 = pages.addPage('knowledge', { mobileBreakpoint: 500 });
page5.addRow(row => {
row.addTextPanel('header5', {
label: 'Step 5 of 6: Market Knowledge',
computedValue: () => 'How prepared are you for the process?',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page5.addSpacer({ height: '24px' });
page5.addRow(row => {
row.addRadioButton('preapproval', {
label: 'Have you been pre-approved for a mortgage?',
options: [
{ id: 'yes', name: 'Yes, I have a pre-approval letter' },
{ id: 'prequalified', name: 'Pre-qualified (not full pre-approval)' },
{ id: 'researching', name: 'Researching lenders but not applied' },
{ id: 'no', name: 'Haven\'t started this process' }
],
orientation: 'vertical',
onValueChange: (v) => {
if (v === 'yes') updateScore('knowledge', 10);
else if (v === 'prequalified') updateScore('knowledge', 7);
else if (v === 'researching') updateScore('knowledge', 4);
else if (v === 'no') updateScore('knowledge', 1);
}
});
});
page5.addRow(row => {
row.addSuggestionChips('completed', {
label: 'Which steps have you completed?',
suggestions: [
{ id: 'budget', name: '📊 Set budget' },
{ id: 'area', name: '📍 Chosen area' },
{ id: 'agent', name: '🏠 Found agent' },
{ id: 'toured', name: '👀 Toured homes' },
{ id: 'costs', name: '💰 Know closing costs' }
],
onValueChange: (v) => {
const count = (v || []).length;
updateScore('knowledge', Math.min(count * 2, 10));
}
});
});
// ========== PAGE 6: Results ==========
const page6 = pages.addPage('results', { mobileBreakpoint: 500 });
page6.addRow(row => {
row.addTextPanel('header6', {
label: 'Step 6 of 6: Your Readiness Score',
computedValue: () => 'Here\'s where you stand',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page6.addSpacer({ height: '24px' });
page6.addRow(row => {
row.addTextPanel('mainScore', {
label: 'Home Buying Readiness',
computedValue: () => `${getScorePercentage()}%`,
customStyles: () => {
const score = getScorePercentage();
return {
fontSize: '56px',
fontWeight: 'bold',
textAlign: 'center',
padding: '20px',
borderRadius: '12px',
color: score >= 65 ? '#059669' : score >= 50 ? '#ca8a04' : '#dc2626',
background: score >= 65 ? '#ecfdf5' : score >= 50 ? '#fefce8' : '#fef2f2'
};
}
});
});
page6.addRow(row => {
row.addTextPanel('readinessLevel', {
label: '',
computedValue: () => getReadinessLabel(),
customStyles: { textAlign: 'center', fontSize: '24px', fontWeight: 'bold', padding: '10px' }
});
});
page6.addRow(row => {
row.addTextPanel('description', {
label: '',
computedValue: () => getReadinessDescription(),
customStyles: { textAlign: 'center', padding: '15px', background: '#f9fafb', borderRadius: '8px' }
});
});
const categorySection = page6.addSubform('categoryBreakdown', {
title: '📊 Category Breakdown (click to expand)',
isCollapsible: true,
customStyles: { background: '#f9fafb', borderRadius: '8px', marginTop: '20px' }
});
categorySection.addRow(row => {
row.addTextPanel('financialScore', {
label: '💼 Income & Debt',
computedValue: () => `${getCategoryScore('financial')}%`,
customStyles: () => ({
padding: '10px',
background: getCategoryScore('financial') >= 60 ? '#ecfdf5' : '#fef2f2',
borderRadius: '4px'
})
});
row.addTextPanel('creditScore', {
label: '📊 Credit',
computedValue: () => `${getCategoryScore('credit')}%`,
customStyles: () => ({
padding: '10px',
background: getCategoryScore('credit') >= 60 ? '#ecfdf5' : '#fef2f2',
borderRadius: '4px'
})
});
});
categorySection.addRow(row => {
row.addTextPanel('savingsScore', {
label: '💰 Savings',
computedValue: () => `${getCategoryScore('savings')}%`,
customStyles: () => ({
padding: '10px',
background: getCategoryScore('savings') >= 60 ? '#ecfdf5' : '#fef2f2',
borderRadius: '4px'
})
});
row.addTextPanel('stabilityScore', {
label: '🏠 Stability',
computedValue: () => `${getCategoryScore('stability')}%`,
customStyles: () => ({
padding: '10px',
background: getCategoryScore('stability') >= 60 ? '#ecfdf5' : '#fef2f2',
borderRadius: '4px'
})
});
});
categorySection.addRow(row => {
row.addTextPanel('knowledgeScore', {
label: '📚 Knowledge',
computedValue: () => `${getCategoryScore('knowledge')}%`,
customStyles: () => ({
padding: '10px',
background: getCategoryScore('knowledge') >= 60 ? '#ecfdf5' : '#fef2f2',
borderRadius: '4px'
})
});
row.addEmpty('1fr');
});
page6.addRow(row => {
row.addTextPanel('focusArea', {
label: '🎯 Priority Focus',
computedValue: () => `Work on ${getCategoryLabel(getWeakestArea())} to improve your readiness.`,
customStyles: { padding: '15px', background: '#fef3c7', borderRadius: '8px', marginTop: '15px' }
});
});
// ========== PAGE 7: Lead Capture ==========
const page7 = pages.addPage('lead-capture', { mobileBreakpoint: 500 });
page7.addRow(row => {
row.addTextPanel('header7', {
label: 'Get Your Home Buying Action Plan',
computedValue: () => 'We\'ll send you personalized next steps',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page7.addSpacer({ height: '24px' });
page7.addRow(row => {
row.addTextbox('name', { label: 'Your Name', isRequired: true, placeholder: 'Jane Smith' }, '1fr');
row.addEmail('email', { label: 'Email', isRequired: true, placeholder: 'jane@email.com' }, '1fr');
});
page7.addRow(row => {
row.addTextbox('phone', { label: 'Phone (optional)', placeholder: '(555) 123-4567' }, '1fr');
row.addDropdown('timeline', {
label: 'When do you hope to buy?',
options: [
{ id: 'asap', name: 'As soon as possible' },
{ id: '6months', name: 'Within 6 months' },
{ id: '1year', name: 'Within 1 year' },
{ id: 'later', name: '1-2 years' },
{ id: 'unsure', name: 'Just exploring' }
]
}, '1fr');
});
page7.addRow(row => {
row.addCheckboxList('consent', {
options: [
{ id: 'plan', name: '📄 Send me my personalized action plan', isRequired: true },
{ id: 'lender', name: '🏦 Connect me with a mortgage lender' },
{ id: 'agent', name: '🏠 Help me find a buyer\'s agent' }
],
defaultValue: ['plan'],
orientation: 'vertical'
});
});
// ========== SUBMIT BUTTON ==========
form.configureSubmitButton({
label: () => `🏠 Get My Action Plan (Score: ${getScorePercentage()}%)`
});
// ========== PDF REPORT ==========
form.configurePdf('home-buying-report', pdf => {
pdf.configure({
filename: 'home-buying-readiness-report.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: '🏠 Download Action Plan',
header: {
title: 'Home Buying Readiness',
subtitle: 'Your Personalized Action Plan'
},
footer: {
text: 'Generated by FormTs',
showPageNumbers: true
}
});
pdf.addSection('Your Readiness Score', section => {
section.addRow(row => {
row.addField('Overall Score', `${getScorePercentage()}%`);
row.addField('Status', getReadinessLabel());
});
section.addText(getReadinessDescription());
});
pdf.addSection('Category Breakdown', section => {
section.addTable(
['Category', 'Score', 'Status'],
[
['Income & Debt', `${getCategoryScore('financial')}%`, getCategoryScore('financial') >= 60 ? '✅' : '⚠️'],
['Credit Score', `${getCategoryScore('credit')}%`, getCategoryScore('credit') >= 60 ? '✅' : '⚠️'],
['Savings', `${getCategoryScore('savings')}%`, getCategoryScore('savings') >= 60 ? '✅' : '⚠️'],
['Life Stability', `${getCategoryScore('stability')}%`, getCategoryScore('stability') >= 60 ? '✅' : '⚠️'],
['Market Knowledge', `${getCategoryScore('knowledge')}%`, getCategoryScore('knowledge') >= 60 ? '✅' : '⚠️']
]
);
});
pdf.addPageBreak();
pdf.addSection('Your Action Plan', section => {
section.addText(`Priority Focus: ${getCategoryLabel(getWeakestArea())}`);
section.addSpacer(10);
section.addText('1. Check your credit report for errors (free at annualcreditreport.com)');
section.addText('2. Calculate your target home price (2.5-3x annual income)');
section.addText('3. Get pre-approved by 2-3 lenders to compare rates');
section.addText('4. Save for down payment + closing costs (2-5% of price)');
section.addText('5. Build emergency fund for unexpected home costs');
section.addText('6. Research neighborhoods and interview real estate agents');
});
pdf.addSection('Important Numbers', section => {
section.addText('• Minimum credit score: 620 (conventional), 580 (FHA)');
section.addText('• Ideal debt-to-income: Under 36% (max 43%)');
section.addText('• Down payment: 3-20% (20% avoids PMI)');
section.addText('• Closing costs: 2-5% of home price');
section.addText('• Reserves needed: 2-6 months mortgage payments');
});
});
form.configureSubmitBehavior({ sendToServer: true });
}