export function startupInvestmentReadinessQuiz(form: FormTs) {
form.setTitle(() => '🚀 Is Your Startup Ready for Investment?');
// ============ SCORING SYSTEM ============
const scores = form.state<Record<string, number>>({});
const updateScore = (category: string, points: number) => {
scores.update(current => ({ ...current, [category]: points }));
};
const getTotalScore = () => {
const s = scores();
return Object.values(s).reduce((sum, val) => sum + (val || 0), 0);
};
const getMaxScore = () => 100;
const getScorePercentage = () => Math.round((getTotalScore() / getMaxScore()) * 100);
const getReadinessLevel = (): 'not-ready' | 'early' | 'developing' | 'ready' => {
const pct = getScorePercentage();
if (pct >= 80) return 'ready';
if (pct >= 60) return 'developing';
if (pct >= 40) return 'early';
return 'not-ready';
};
const getReadinessLabel = () => {
const level = getReadinessLevel();
const labels = {
'not-ready': '🔴 Not Investment Ready',
'early': '🟡 Early Stage - Keep Building',
'developing': '🟠 Developing - Almost There',
'ready': '🟢 Investment Ready!'
};
return labels[level];
};
const getReadinessColor = () => {
const level = getReadinessLevel();
const colors = {
'not-ready': '#dc2626',
'early': '#ca8a04',
'developing': '#ea580c',
'ready': '#16a34a'
};
return colors[level];
};
// ============ COMPLETION SCREEN ============
form.configureCompletionScreen({
type: 'text',
title: () => getReadinessLabel(),
message: () => {
const pct = getScorePercentage();
const level = getReadinessLevel();
const messages = {
'not-ready': `Your readiness score is ${pct}%. Focus on building your product and finding product-market fit before approaching investors. Download your detailed report for specific next steps.`,
'early': `Your readiness score is ${pct}%. You're making progress! Consider bootstrapping or friends & family rounds while you strengthen key areas.`,
'developing': `Your readiness score is ${pct}%. You're close to being investor-ready. Address the gaps in your report to maximize your chances.`,
'ready': `Congratulations! Your readiness score is ${pct}%. Your startup shows strong fundamentals for investment. Review your report to prepare for investor conversations.`
};
return messages[level];
}
});
// ============ PAGES SETUP ============
const pages = form.addPages('quiz-pages', {
heightMode: 'current-page'
});
// ============ PAGE 1: Company Basics ============
const page1 = pages.addPage('company-basics', { mobileBreakpoint: 500 });
page1.addRow(row => {
row.addTextPanel('header1', {
label: 'Step 1 of 7: Company Basics',
computedValue: () => 'Let\'s understand your startup\'s current stage',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page1.addSpacer({ height: '24px' });
page1.addRow(row => {
row.addDropdown('stage', {
label: 'What stage is your startup?',
isRequired: true,
options: [
{ id: 'idea', name: '💭 Idea stage - concept only' },
{ id: 'prototype', name: '🔧 Prototype/MVP in development' },
{ id: 'launched', name: '🚀 Product launched, early users' },
{ id: 'traction', name: '📈 Growing with consistent traction' },
{ id: 'scaling', name: '🌍 Scaling with proven model' }
],
placeholder: 'Select your stage',
onValueChange: (val) => {
const points = { idea: 2, prototype: 5, launched: 10, traction: 15, scaling: 20 };
updateScore('stage', points[val as keyof typeof points] || 0);
}
}, '1fr');
row.addDropdown('industry', {
label: 'Industry/Sector',
isRequired: true,
options: [
{ id: 'saas', name: '💻 SaaS/Software' },
{ id: 'fintech', name: '💳 Fintech' },
{ id: 'healthtech', name: '🏥 Healthtech' },
{ id: 'ecommerce', name: '🛒 E-commerce' },
{ id: 'marketplace', name: '🏪 Marketplace' },
{ id: 'hardware', name: '🔌 Hardware/IoT' },
{ id: 'ai', name: '🤖 AI/ML' },
{ id: 'other', name: '📦 Other' }
],
placeholder: 'Select industry'
}, '1fr');
});
page1.addRow(row => {
row.addSlider('teamSize', {
label: 'Full-time team size',
isRequired: true,
min: 1,
max: 50,
step: 1,
defaultValue: 2,
showValue: true,
unit: 'people',
onValueChange: (val) => {
if (val == null) return;
let points = 0;
if (val >= 3 && val <= 10) points = 5;
else if (val > 10) points = 3;
else points = 2;
updateScore('teamSize', points);
}
});
});
// ============ PAGE 2: Product & Market ============
const page2 = pages.addPage('product-market', { mobileBreakpoint: 500 });
page2.addRow(row => {
row.addTextPanel('header2', {
label: 'Step 2 of 7: Product & Market',
computedValue: () => 'Understanding your product-market fit',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page2.addSpacer({ height: '24px' });
page2.addRow(row => {
row.addRadioButton('pmf', {
label: 'Do you have product-market fit?',
tooltip: 'Product-market fit means users love your product and would be very disappointed if it went away',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'strong', name: '🎯 Strong PMF - users love it, organic growth, retention is high' },
{ id: 'emerging', name: '📈 Emerging PMF - seeing positive signals, iterating fast' },
{ id: 'searching', name: '🔍 Still searching - testing hypotheses' },
{ id: 'unknown', name: '❓ Not sure yet' }
],
onValueChange: (val) => {
const points = { strong: 15, emerging: 10, searching: 5, unknown: 2 };
updateScore('pmf', points[val as keyof typeof points] || 0);
}
});
});
page2.addRow(row => {
row.addRadioButton('tam', {
label: 'How big is your total addressable market (TAM)?',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'billion', name: '🌍 $1B+ - massive market opportunity' },
{ id: 'hundreds', name: '💰 $100M-$1B - large market' },
{ id: 'tens', name: '📊 $10M-$100M - decent market' },
{ id: 'small', name: '📉 Under $10M - niche market' },
{ id: 'unknown', name: '🤷 Haven\'t calculated yet' }
],
onValueChange: (val) => {
const points = { billion: 10, hundreds: 8, tens: 5, small: 2, unknown: 0 };
updateScore('tam', points[val as keyof typeof points] || 0);
}
});
});
page2.addRow(row => {
row.addTextPanel('productScore', {
computedValue: () => {
const s = scores();
const sectionScore = (s['stage'] || 0) + (s['pmf'] || 0) + (s['tam'] || 0);
return `📦 Product & Market Score: ${sectionScore}/45`;
},
customStyles: () => {
const s = scores();
const sectionScore = (s['stage'] || 0) + (s['pmf'] || 0) + (s['tam'] || 0);
const color = sectionScore >= 35 ? '#059669' : sectionScore >= 25 ? '#ca8a04' : '#dc2626';
return {
fontSize: '1rem',
fontWeight: '600',
color: color,
textAlign: 'center',
padding: '12px',
background: sectionScore >= 35 ? '#ecfdf5' : sectionScore >= 25 ? '#fefce8' : '#fef2f2',
borderRadius: '8px',
marginTop: '1rem',
border: `2px solid ${color}`
};
}
});
});
// ============ PAGE 3: Traction & Metrics ============
const page3 = pages.addPage('traction', { mobileBreakpoint: 500 });
page3.addRow(row => {
row.addTextPanel('header3', {
label: 'Step 3 of 7: Traction & Metrics',
computedValue: () => 'Investors love numbers - let\'s see yours',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page3.addSpacer({ height: '24px' });
page3.addRow(row => {
row.addRadioButton('revenue', {
label: 'What\'s your current Monthly Recurring Revenue (MRR)?',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'pre', name: '💭 Pre-revenue' },
{ id: 'under10k', name: '💵 Under $10K MRR' },
{ id: '10k-50k', name: '💰 $10K-$50K MRR' },
{ id: '50k-100k', name: '🤑 $50K-$100K MRR' },
{ id: 'over100k', name: '🚀 Over $100K MRR' }
],
onValueChange: (val) => {
const points = { pre: 0, 'under10k': 3, '10k-50k': 7, '50k-100k': 12, 'over100k': 15 };
updateScore('revenue', points[val as keyof typeof points] || 0);
}
});
});
page3.addRow(row => {
row.addRatingScale('growthRate', {
label: 'Month-over-month growth rate',
isRequired: true,
preset: 'custom',
min: 0,
max: 5,
lowLabel: '0% or negative',
highLabel: '20%+ growth',
size: 'md',
alignment: 'center',
variant: 'segmented',
onValueChange: (val) => {
if (val == null) return;
const points = [0, 2, 4, 6, 8, 10];
updateScore('growth', points[val] || 0);
}
});
});
page3.addRow(row => {
row.addTextPanel('growthHint', {
computedValue: () => {
const val = page3.ratingScale('growthRate')?.value();
if (val === 0) return '0 = Flat or declining';
if (val === 1) return '1 = 1-5% monthly growth';
if (val === 2) return '2 = 5-10% monthly growth';
if (val === 3) return '3 = 10-15% monthly growth';
if (val === 4) return '4 = 15-20% monthly growth';
if (val === 5) return '5 = 20%+ monthly growth (excellent!)';
return 'Select your growth rate';
},
customStyles: {
fontSize: '0.8rem',
color: '#6b7280',
textAlign: 'center',
marginTop: '0.25rem'
}
});
});
page3.addRow(row => {
row.addTextPanel('tractionScore', {
computedValue: () => {
const s = scores();
const sectionScore = (s['revenue'] || 0) + (s['growth'] || 0);
return `📈 Traction Score: ${sectionScore}/25`;
},
customStyles: {
fontSize: '1rem',
fontWeight: '600',
color: '#1e40af',
textAlign: 'center',
padding: '12px',
background: '#dbeafe',
borderRadius: '8px',
marginTop: '1rem'
}
});
});
// ============ PAGE 4: Team & Execution ============
const page4 = pages.addPage('team', { mobileBreakpoint: 500 });
page4.addRow(row => {
row.addTextPanel('header4', {
label: 'Step 4 of 7: Team & Execution',
computedValue: () => 'VCs bet on teams as much as ideas',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page4.addSpacer({ height: '24px' });
page4.addRow(row => {
row.addMatrixQuestion('teamMatrix', {
label: 'Rate your founding team on these dimensions:',
isRequired: true,
rows: [
{ id: 'domain', label: 'Domain Expertise', description: 'Deep knowledge of the industry' },
{ id: 'technical', label: 'Technical Capability', description: 'Can build the product' },
{ id: 'startup', label: 'Startup Experience', description: 'Previous founding/early-stage experience' }
],
columns: [
{ id: 'weak', label: 'Weak' },
{ id: 'moderate', label: 'Moderate' },
{ id: 'strong', label: 'Strong' },
{ id: 'exceptional', label: 'Exceptional' }
],
selectionMode: 'single',
striped: true,
fullWidth: true,
onValueChange: (val) => {
if (!val) return;
const pointsMap: Record<string, Record<string, number>> = {
domain: { weak: 0, moderate: 2, strong: 4, exceptional: 5 },
technical: { weak: 0, moderate: 2, strong: 4, exceptional: 5 },
startup: { weak: 0, moderate: 1, strong: 3, exceptional: 5 }
};
let total = 0;
for (const [row, col] of Object.entries(val)) {
if (col && pointsMap[row]) {
total += pointsMap[row][col as string] || 0;
}
}
updateScore('team', total);
}
});
});
page4.addRow(row => {
row.addTextPanel('teamScore', {
computedValue: () => {
const s = scores();
return `👥 Team Score: ${s['team'] || 0}/15`;
},
customStyles: {
fontSize: '1rem',
fontWeight: '600',
color: '#1e40af',
textAlign: 'center',
padding: '12px',
background: '#dbeafe',
borderRadius: '8px',
marginTop: '1rem'
}
});
});
// ============ PAGE 5: Fundraising Readiness ============
const page5 = pages.addPage('fundraising', { mobileBreakpoint: 500 });
page5.addRow(row => {
row.addTextPanel('header5', {
label: 'Step 5 of 7: Fundraising Readiness',
computedValue: () => 'Are you prepared for the fundraising process?',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page5.addSpacer({ height: '24px' });
page5.addRow(row => {
row.addSuggestionChips('materials', {
label: 'Which fundraising materials do you have ready?',
isRequired: true,
suggestions: [
{ id: 'deck', name: '📊 Pitch Deck' },
{ id: 'financials', name: '📈 Financial Model' },
{ id: 'dataroom', name: '📁 Data Room' },
{ id: 'onepager', name: '📄 One-Pager' },
{ id: 'demo', name: '🎥 Product Demo' }
],
min: 0,
alignment: 'center',
onValueChange: (val) => {
if (!val) return;
updateScore('materials', val.length * 2);
}
});
});
page5.addRow(row => {
row.addRadioButton('network', {
label: 'How strong is your investor network?',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'strong', name: '🌐 Strong - warm intros to many VCs/angels' },
{ id: 'some', name: '🤝 Some connections - a few warm intros possible' },
{ id: 'building', name: '🌱 Building - actively networking' },
{ id: 'none', name: '❌ None - starting from scratch' }
],
onValueChange: (val) => {
const points = { strong: 5, some: 3, building: 1, none: 0 };
updateScore('network', points[val as keyof typeof points] || 0);
}
});
});
page5.addRow(row => {
row.addTextPanel('readinessScore', {
computedValue: () => {
const s = scores();
const sectionScore = (s['materials'] || 0) + (s['network'] || 0);
return `📋 Fundraising Readiness Score: ${sectionScore}/15`;
},
customStyles: {
fontSize: '1rem',
fontWeight: '600',
color: '#1e40af',
textAlign: 'center',
padding: '12px',
background: '#dbeafe',
borderRadius: '8px',
marginTop: '1rem'
}
});
});
// ============ PAGE 6: Results ============
const page6 = pages.addPage('results', { mobileBreakpoint: 500 });
page6.addRow(row => {
row.addTextPanel('header6', {
label: 'Step 6 of 7: Your Results',
computedValue: () => 'Your investment readiness assessment',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page6.addSpacer({ height: '24px' });
page6.addRow(row => {
row.addTextPanel('finalScoreLabel', {
label: '🚀 Investment Readiness Assessment',
computedValue: () => '',
customStyles: {
fontSize: '1.2rem',
fontWeight: '700',
textAlign: 'center'
}
});
});
page6.addRow(row => {
row.addTextPanel('finalReadiness', {
computedValue: () => getReadinessLabel(),
customStyles: {
fontSize: '1.5rem',
fontWeight: '800',
textAlign: 'center',
color: getReadinessColor(),
padding: '15px',
background: '#f9fafb',
borderRadius: '12px',
border: `3px solid ${getReadinessColor()}`
}
});
});
page6.addRow(row => {
row.addTextPanel('scoreBreakdown', {
computedValue: () => {
const total = getTotalScore();
const pct = getScorePercentage();
return `Total Score: ${total}/${getMaxScore()} (${pct}%)`;
},
customStyles: {
fontSize: '1.1rem',
fontWeight: '600',
textAlign: 'center',
color: '#374151',
marginTop: '10px'
}
});
});
page6.addRow(row => {
row.addTextPanel('recommendation', {
computedValue: () => {
const level = getReadinessLevel();
const recommendations = {
'not-ready': '🔴 Focus on building your product and finding early customers before seeking investment. Most VCs want to see traction first.',
'early': '🟡 You\'re making progress! Consider bootstrapping, accelerators, or angel investors while you build more traction.',
'developing': '🟠 You\'re close! Address the gaps in your fundraising materials and network before starting your raise.',
'ready': '🟢 You\'re in a strong position! Prepare your materials, practice your pitch, and start reaching out to investors.'
};
return recommendations[level];
},
customStyles: {
fontSize: '0.95rem',
color: '#4b5563',
textAlign: 'center',
padding: '15px',
background: '#f3f4f6',
borderRadius: '8px',
marginTop: '15px',
lineHeight: '1.5'
}
});
});
// Collapsible detailed breakdown
const detailsSection = page6.addSubform('detailsBreakdown', {
title: '📊 Detailed Score Breakdown (click to expand)',
isCollapsible: true,
customStyles: {
marginTop: '1rem',
background: '#f9fafb',
borderRadius: '8px'
}
});
detailsSection.addRow(row => {
row.addTextPanel('productDetail', {
label: '📦 Product & Market',
computedValue: () => {
const s = scores();
const score = (s['stage'] || 0) + (s['pmf'] || 0) + (s['tam'] || 0);
return `${score}/45 points`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
row.addTextPanel('tractionDetail', {
label: '📈 Traction',
computedValue: () => {
const s = scores();
const score = (s['revenue'] || 0) + (s['growth'] || 0);
return `${score}/25 points`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
});
detailsSection.addRow(row => {
row.addTextPanel('teamDetail', {
label: '👥 Team',
computedValue: () => {
const s = scores();
return `${s['team'] || 0}/15 points`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
row.addTextPanel('readinessDetail', {
label: '📋 Fundraising Readiness',
computedValue: () => {
const s = scores();
const score = (s['materials'] || 0) + (s['network'] || 0);
return `${score}/15 points`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
});
// ============ PAGE 7: Lead Capture ============
const page7 = pages.addPage('lead-capture', { mobileBreakpoint: 500 });
page7.addRow(row => {
row.addTextPanel('header7', {
label: 'Step 7 of 7: Get Your Report',
computedValue: () => 'Enter your details to receive your personalized investment readiness report',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page7.addSpacer({ height: '24px' });
page7.addRow(row => {
row.addTextPanel('leadCapture', {
label: '📧 Get Your Investment Readiness Report',
computedValue: () => 'Receive a detailed PDF with your scores, gaps, and action items',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280'
}
});
});
page7.addRow(row => {
row.addTextbox('name', {
label: 'Your Name',
isRequired: true,
placeholder: 'John Smith'
}, '1fr');
row.addEmail('email', {
label: 'Work Email',
isRequired: true,
placeholder: 'john@startup.com'
}, '1fr');
});
page7.addRow(row => {
row.addTextbox('company', {
label: 'Startup Name',
placeholder: 'Acme Startup Inc.'
}, '1fr');
row.addTextbox('role', {
label: 'Your Role',
placeholder: 'CEO / Co-founder'
}, '1fr');
});
page7.addRow(row => {
row.addCheckboxList('consent', {
options: [
{ id: 'report', name: '📄 Send me my detailed investment readiness report', isRequired: true },
{ id: 'tips', name: '💡 Send me fundraising tips and investor insights' },
{ id: 'intro', name: '📞 I\'d like to connect with startup mentors' }
],
defaultValue: ['report'],
orientation: 'vertical'
});
});
// ============ PDF REPORT ============
form.configurePdf('investment-readiness-report', pdf => {
pdf.configure({
filename: 'startup-investment-readiness-report.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: '📄 Download Readiness Report',
header: {
title: 'Startup Investment Readiness Report',
subtitle: 'Your Personalized Fundraising Assessment'
},
footer: {
text: 'Generated by FormTs Investment Readiness Quiz',
showPageNumbers: true
}
});
pdf.addSection('Executive Summary', section => {
section.addRow(row => {
row.addField('Readiness Level', getReadinessLabel());
row.addField('Overall Score', `${getScorePercentage()}%`);
});
section.addRow(row => {
row.addField('Assessment Date', new Date().toLocaleDateString());
row.addField('Total Points', `${getTotalScore()} / ${getMaxScore()}`);
});
});
pdf.addSection('Category Breakdown', section => {
const s = scores();
section.addTable(
['Category', 'Score', 'Max', 'Status'],
[
['Product & Market', `${(s['stage'] || 0) + (s['pmf'] || 0) + (s['tam'] || 0)}`, '45', (s['stage'] || 0) + (s['pmf'] || 0) + (s['tam'] || 0) >= 35 ? '✅ Strong' : '⚠️ Needs Work'],
['Traction', `${(s['revenue'] || 0) + (s['growth'] || 0)}`, '25', (s['revenue'] || 0) + (s['growth'] || 0) >= 18 ? '✅ Strong' : '⚠️ Needs Work'],
['Team', `${s['team'] || 0}`, '15', (s['team'] || 0) >= 12 ? '✅ Strong' : '⚠️ Needs Work'],
['Fundraising Readiness', `${(s['materials'] || 0) + (s['network'] || 0)}`, '15', (s['materials'] || 0) + (s['network'] || 0) >= 10 ? '✅ Strong' : '⚠️ Needs Work'],
]
);
});
pdf.addPageBreak();
pdf.addSection('Recommendations', section => {
const level = getReadinessLevel();
if (level === 'not-ready' || level === 'early') {
section.addText('1. Focus on achieving product-market fit before fundraising');
section.addText('2. Build a working MVP and get initial customers');
section.addText('3. Start tracking key metrics from day one');
section.addText('4. Consider bootstrapping or friends & family rounds first');
} else if (level === 'developing') {
section.addText('1. Complete your pitch deck and financial model');
section.addText('2. Set up a proper data room with key documents');
section.addText('3. Start building relationships with investors now');
section.addText('4. Practice your pitch and refine your story');
} else {
section.addText('1. Finalize your fundraising materials');
section.addText('2. Create a targeted investor list');
section.addText('3. Leverage warm introductions whenever possible');
section.addText('4. Prepare for due diligence questions');
}
});
});
// ============ SUBMIT BUTTON ============
form.configureSubmitButton({
label: () => `🚀 Get My Readiness Report (Score: ${getScorePercentage()}%)`
});
form.configureSubmitBehavior({
sendToServer: true
});
}