export function realEstateLegalFeesCalculator(form: FormTs) {
// Transaction types and base fees
const transactionTypes: Record<string, { baseFee: number, percentageBased: boolean, percentage?: number }> = {
'residential-purchase': { baseFee: 750, percentageBased: false },
'residential-sale': { baseFee: 650, percentageBased: false },
'refinance': { baseFee: 500, percentageBased: false },
'commercial-purchase': { baseFee: 2500, percentageBased: true, percentage: 0.003 },
'commercial-sale': { baseFee: 2000, percentageBased: true, percentage: 0.0025 },
'commercial-lease': { baseFee: 1500, percentageBased: false },
'investment-property': { baseFee: 1200, percentageBased: false },
'new-construction': { baseFee: 1000, percentageBased: false },
'short-sale': { baseFee: 1500, percentageBased: false },
'foreclosure': { baseFee: 1200, percentageBased: false },
'1031-exchange': { baseFee: 2000, percentageBased: false }
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Real Estate Transaction Legal Fees Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Transaction Type Section
const transactionSection = form.addSubform('transaction', { title: '๐ Transaction Details' });
transactionSection.addRow(row => {
row.addDropdown('type', {
label: 'Transaction Type',
options: [
{ id: 'residential-purchase', name: 'Residential Purchase' },
{ id: 'residential-sale', name: 'Residential Sale' },
{ id: 'refinance', name: 'Refinance' },
{ id: 'commercial-purchase', name: 'Commercial Purchase' },
{ id: 'commercial-sale', name: 'Commercial Sale' },
{ id: 'commercial-lease', name: 'Commercial Lease' },
{ id: 'investment-property', name: 'Investment Property' },
{ id: 'new-construction', name: 'New Construction' },
{ id: 'short-sale', name: 'Short Sale' },
{ id: 'foreclosure', name: 'Foreclosure Purchase' },
{ id: '1031-exchange', name: '1031 Exchange' }
],
defaultValue: 'residential-purchase',
isRequired: true
}, '1fr');
row.addDropdown('role', {
label: 'Your Role',
options: [
{ id: 'buyer', name: 'Buyer' },
{ id: 'seller', name: 'Seller' },
{ id: 'both', name: 'Both (Investment)' }
],
defaultValue: 'buyer',
isRequired: true
}, '1fr');
});
transactionSection.addRow(row => {
row.addMoney('propertyValue', {
label: 'Property Value / Purchase Price',
defaultValue: 350000,
min: 50000,
isRequired: true
}, '1fr');
row.addDropdown('propertyType', {
label: 'Property Type',
options: [
{ id: 'single-family', name: 'Single Family Home' },
{ id: 'condo', name: 'Condo / Co-op' },
{ id: 'multi-family', name: 'Multi-Family (2-4 units)' },
{ id: 'apartment', name: 'Apartment Building' },
{ id: 'commercial', name: 'Commercial Property' },
{ id: 'land', name: 'Vacant Land' },
{ id: 'mixed-use', name: 'Mixed Use' }
],
defaultValue: 'single-family',
isRequired: true
}, '1fr');
});
// Location Section
const locationSection = form.addSubform('location', { title: '๐ Location & Complexity' });
locationSection.addRow(row => {
row.addDropdown('state', {
label: 'State',
options: [
{ id: 'attorney-required', name: 'Attorney Required State (NY, NJ, MA, CT, etc.)' },
{ id: 'attorney-optional', name: 'Attorney Optional State' },
{ id: 'escrow-state', name: 'Escrow State (CA, WA, etc.)' }
],
defaultValue: 'attorney-optional',
isRequired: true
}, '1fr');
row.addDropdown('complexity', {
label: 'Transaction Complexity',
options: [
{ id: 'simple', name: 'Simple / Standard' },
{ id: 'moderate', name: 'Moderate (+25%)' },
{ id: 'complex', name: 'Complex (+50%)' },
{ id: 'highly-complex', name: 'Highly Complex (+100%)' }
],
defaultValue: 'simple',
isRequired: true
}, '1fr');
});
locationSection.addRow(row => {
row.addCheckbox('titleIssues', {
label: 'Potential Title Issues (+$500)',
defaultValue: false
}, '1fr');
row.addCheckbox('zoningIssues', {
label: 'Zoning / Permit Review (+$400)',
defaultValue: false
}, '1fr');
});
// Services Section
const servicesSection = form.addSubform('services', { title: '๐ Legal Services' });
servicesSection.addRow(row => {
row.addCheckbox('contractReview', {
label: 'Contract Review & Negotiation (+$350)',
defaultValue: true
}, '1fr');
row.addCheckbox('dueDiligence', {
label: 'Due Diligence Coordination (+$400)',
defaultValue: true
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('titleSearch', {
label: 'Title Search & Examination (+$300)',
defaultValue: true
}, '1fr');
row.addCheckbox('titleInsurance', {
label: 'Title Insurance Coordination (+$150)',
defaultValue: true
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('closingAttendance', {
label: 'Closing Attendance (+$250)',
defaultValue: true
}, '1fr');
row.addCheckbox('documentPrep', {
label: 'Document Preparation (+$200)',
defaultValue: true
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('mortgageReview', {
label: 'Mortgage Document Review (+$250)',
defaultValue: false
}, '1fr');
row.addCheckbox('escrowServices', {
label: 'Escrow Services (+$300)',
defaultValue: false
}, '1fr');
});
// Special Situations Section
const specialSection = form.addSubform('special', { title: 'โ ๏ธ Special Situations' });
specialSection.addRow(row => {
row.addCheckbox('estateSale', {
label: 'Estate / Probate Sale (+$500)',
defaultValue: false
}, '1fr');
row.addCheckbox('relocation', {
label: 'Relocation Package (+$300)',
defaultValue: false
}, '1fr');
});
specialSection.addRow(row => {
row.addCheckbox('hoaReview', {
label: 'HOA Document Review (+$200)',
defaultValue: false
}, '1fr');
row.addCheckbox('leaseReview', {
label: 'Existing Lease Review (+$350)',
defaultValue: false,
isVisible: () => {
const type = transactionSection.dropdown('type')?.value();
return ['investment-property', 'commercial-purchase', 'multi-family'].includes(type || '');
}
}, '1fr');
});
specialSection.addRow(row => {
row.addCheckbox('entityFormation', {
label: 'Entity Formation (LLC) (+$600)',
defaultValue: false
}, '1fr');
row.addCheckbox('negotiationSupport', {
label: 'Extended Negotiation Support (+$500)',
defaultValue: false
}, '1fr');
});
// Timeline Section
const timelineSection = form.addSubform('timeline', { title: 'โฐ Timeline' });
timelineSection.addRow(row => {
row.addDropdown('urgency', {
label: 'Transaction Timeline',
options: [
{ id: 'standard', name: 'Standard (30-45 days)' },
{ id: 'expedited', name: 'Expedited (15-30 days) (+20%)' },
{ id: 'rush', name: 'Rush (Under 15 days) (+40%)' }
],
defaultValue: 'standard',
isRequired: true
}, '1fr');
row.addCheckbox('weekendClosing', {
label: 'Weekend/Holiday Closing (+$200)',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Summary Section
const summarySection = form.addSubform('summary', { title: '๐ฐ Fee Estimate', isCollapsible: false });
summarySection.addRow(row => {
row.addPriceDisplay('baseFee', {
label: 'Base Legal Fee',
computedValue: () => {
const type = transactionSection.dropdown('type')?.value() || 'residential-purchase';
const propertyValue = transactionSection.money('propertyValue')?.value() || 350000;
const complexity = locationSection.dropdown('complexity')?.value() || 'simple';
const state = locationSection.dropdown('state')?.value() || 'attorney-optional';
const transactionInfo = transactionTypes[type];
let fee = transactionInfo?.baseFee ?? 0;
// Percentage-based for commercial
if (transactionInfo?.percentageBased && transactionInfo.percentage) {
fee = Math.max(fee, propertyValue * transactionInfo.percentage);
}
// Value-based adjustment for residential
if (!transactionInfo?.percentageBased && propertyValue > 500000) {
fee += (propertyValue - 500000) * 0.0005;
}
// Complexity multiplier
const complexityMultipliers: Record<string, number> = {
'simple': 1.0, 'moderate': 1.25, 'complex': 1.5, 'highly-complex': 2.0
};
fee *= complexityMultipliers[complexity] || 1.0;
// State adjustment
if (state === 'attorney-required') fee *= 1.15;
return Math.round(fee);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('servicesFee', {
label: 'Selected Services',
computedValue: () => {
let total = 0;
if (servicesSection.checkbox('contractReview')?.value()) total += 350;
if (servicesSection.checkbox('dueDiligence')?.value()) total += 400;
if (servicesSection.checkbox('titleSearch')?.value()) total += 300;
if (servicesSection.checkbox('titleInsurance')?.value()) total += 150;
if (servicesSection.checkbox('closingAttendance')?.value()) total += 250;
if (servicesSection.checkbox('documentPrep')?.value()) total += 200;
if (servicesSection.checkbox('mortgageReview')?.value()) total += 250;
if (servicesSection.checkbox('escrowServices')?.value()) total += 300;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('specialFee', {
label: 'Special Situations',
computedValue: () => {
let total = 0;
if (locationSection.checkbox('titleIssues')?.value()) total += 500;
if (locationSection.checkbox('zoningIssues')?.value()) total += 400;
if (specialSection.checkbox('estateSale')?.value()) total += 500;
if (specialSection.checkbox('relocation')?.value()) total += 300;
if (specialSection.checkbox('hoaReview')?.value()) total += 200;
if (specialSection.checkbox('leaseReview')?.value()) total += 350;
if (specialSection.checkbox('entityFormation')?.value()) total += 600;
if (specialSection.checkbox('negotiationSupport')?.value()) total += 500;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
row.addPriceDisplay('timelineFee', {
label: 'Timeline Premium',
computedValue: () => {
const type = transactionSection.dropdown('type')?.value() || 'residential-purchase';
const urgency = timelineSection.dropdown('urgency')?.value() || 'standard';
const baseFee = transactionTypes[type]?.baseFee ?? 0;
let total = 0;
const urgencyMultipliers: Record<string, number> = {
'standard': 0, 'expedited': 0.2, 'rush': 0.4
};
total += baseFee * (urgencyMultipliers[urgency] || 0);
if (timelineSection.checkbox('weekendClosing')?.value()) total += 200;
return Math.round(total);
},
variant: 'default',
prefix: '+'
}, '1fr');
});
const finalSection = form.addSubform('final', {
title: '๐งพ Total Estimate',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('totalFee', {
label: 'Estimated Legal Fees',
computedValue: () => {
const type = transactionSection.dropdown('type')?.value() || 'residential-purchase';
const propertyValue = transactionSection.money('propertyValue')?.value() || 350000;
const complexity = locationSection.dropdown('complexity')?.value() || 'simple';
const state = locationSection.dropdown('state')?.value() || 'attorney-optional';
const urgency = timelineSection.dropdown('urgency')?.value() || 'standard';
// Base fee
const transactionInfo = transactionTypes[type];
let fee = transactionInfo?.baseFee ?? 0;
if (transactionInfo?.percentageBased && transactionInfo.percentage) {
fee = Math.max(fee, propertyValue * transactionInfo.percentage);
}
if (!transactionInfo?.percentageBased && propertyValue > 500000) {
fee += (propertyValue - 500000) * 0.0005;
}
const complexityMultipliers: Record<string, number> = {
'simple': 1.0, 'moderate': 1.25, 'complex': 1.5, 'highly-complex': 2.0
};
fee *= complexityMultipliers[complexity] || 1.0;
if (state === 'attorney-required') fee *= 1.15;
// Services
if (servicesSection.checkbox('contractReview')?.value()) fee += 350;
if (servicesSection.checkbox('dueDiligence')?.value()) fee += 400;
if (servicesSection.checkbox('titleSearch')?.value()) fee += 300;
if (servicesSection.checkbox('titleInsurance')?.value()) fee += 150;
if (servicesSection.checkbox('closingAttendance')?.value()) fee += 250;
if (servicesSection.checkbox('documentPrep')?.value()) fee += 200;
if (servicesSection.checkbox('mortgageReview')?.value()) fee += 250;
if (servicesSection.checkbox('escrowServices')?.value()) fee += 300;
// Special situations
if (locationSection.checkbox('titleIssues')?.value()) fee += 500;
if (locationSection.checkbox('zoningIssues')?.value()) fee += 400;
if (specialSection.checkbox('estateSale')?.value()) fee += 500;
if (specialSection.checkbox('relocation')?.value()) fee += 300;
if (specialSection.checkbox('hoaReview')?.value()) fee += 200;
if (specialSection.checkbox('leaseReview')?.value()) fee += 350;
if (specialSection.checkbox('entityFormation')?.value()) fee += 600;
if (specialSection.checkbox('negotiationSupport')?.value()) fee += 500;
// Timeline
const urgencyMultipliers: Record<string, number> = {
'standard': 1.0, 'expedited': 1.2, 'rush': 1.4
};
fee *= urgencyMultipliers[urgency] || 1.0;
if (timelineSection.checkbox('weekendClosing')?.value()) fee += 200;
return Math.round(fee);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('percentNote', {
computedValue: () => {
const propertyValue = transactionSection.money('propertyValue')?.value() || 350000;
const type = transactionSection.dropdown('type')?.value() || 'residential-purchase';
const transactionInfo = transactionTypes[type];
let baseFee = transactionInfo?.baseFee ?? 0;
if (transactionInfo?.percentageBased && transactionInfo.percentage) {
baseFee = Math.max(baseFee, propertyValue * transactionInfo.percentage);
}
const percentage = (Number((baseFee / propertyValue) * 100) || 0).toFixed(2);
return `Base fee represents approximately ${percentage}% of property value`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#64748b', 'text-align': 'center' }
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'This estimate covers attorney fees only. Additional closing costs (title insurance premiums, recording fees, transfer taxes) are separate. Final fees confirmed after reviewing transaction documents.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Get Transaction Quote'
});
}