export function carPaymentCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Car Payment Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Vehicle Price Section
const vehicleSection = form.addSubform('vehicle', { title: '🚗 Vehicle Price' });
vehicleSection.addRow(row => {
row.addMoney('vehiclePrice', {
label: 'Vehicle Price',
min: 1000,
max: 500000,
defaultValue: 35000,
isRequired: true,
tooltip: 'Sticker price or negotiated price'
}, '1fr');
row.addDropdown('condition', {
label: 'Vehicle Condition',
options: [
{ id: 'new', name: 'New' },
{ id: 'certified', name: 'Certified Pre-Owned' },
{ id: 'used', name: 'Used' }
],
defaultValue: 'new',
tooltip: 'Affects typical interest rates'
}, '1fr');
});
vehicleSection.addRow(row => {
row.addMoney('downPayment', {
label: 'Down Payment',
min: 0,
max: 200000,
defaultValue: 5000,
tooltip: 'Cash you pay upfront'
}, '1fr');
row.addMoney('tradeIn', {
label: 'Trade-in Value',
min: 0,
max: 100000,
defaultValue: 0,
tooltip: 'Value of your current vehicle'
}, '1fr');
});
vehicleSection.addRow(row => {
row.addMoney('tradeInPayoff', {
label: 'Trade-in Loan Payoff',
min: 0,
max: 100000,
defaultValue: 0,
isVisible: () => (vehicleSection.money('tradeIn')?.value() || 0) > 0,
tooltip: 'Amount still owed on trade-in'
});
});
// Taxes & Fees Section
const feesSection = form.addSubform('fees', { title: '📋 Taxes & Fees' });
feesSection.addRow(row => {
row.addDecimal('salesTaxRate', {
label: 'Sales Tax Rate (%)',
min: 0,
max: 15,
defaultValue: 6.5,
tooltip: 'Your state/local sales tax rate'
}, '1fr');
row.addMoney('docFee', {
label: 'Documentation Fee',
min: 0,
max: 2000,
defaultValue: 300,
tooltip: 'Dealer processing fee'
}, '1fr');
});
feesSection.addRow(row => {
row.addMoney('registrationFee', {
label: 'Registration & Title Fees',
min: 0,
max: 2000,
defaultValue: 200,
tooltip: 'State DMV fees'
}, '1fr');
row.addMoney('otherFees', {
label: 'Other Fees',
min: 0,
max: 5000,
defaultValue: 0,
tooltip: 'Additional dealer or lender fees'
}, '1fr');
});
feesSection.addRow(row => {
row.addCheckbox('rollInFees', {
label: 'Include taxes and fees in loan',
defaultValue: true,
tooltip: 'Finance taxes/fees vs. pay upfront'
});
});
// Loan Terms Section
const loanSection = form.addSubform('loan', { title: '💳 Loan Terms' });
loanSection.addRow(row => {
row.addDecimal('interestRate', {
label: 'Interest Rate (APR %)',
min: 0,
max: 30,
defaultValue: 6.5,
isRequired: true,
tooltip: 'Annual percentage rate'
}, '1fr');
row.addDropdown('loanTerm', {
label: 'Loan Term',
options: [
{ id: '24', name: '24 months (2 years)' },
{ id: '36', name: '36 months (3 years)' },
{ id: '48', name: '48 months (4 years)' },
{ id: '60', name: '60 months (5 years)' },
{ id: '72', name: '72 months (6 years)' },
{ id: '84', name: '84 months (7 years)' }
],
defaultValue: '60',
isRequired: true
}, '1fr');
});
loanSection.addRow(row => {
row.addDropdown('creditScore', {
label: 'Your Credit Score',
options: [
{ id: 'excellent', name: 'Excellent (750+)' },
{ id: 'good', name: 'Good (700-749)' },
{ id: 'fair', name: 'Fair (650-699)' },
{ id: 'poor', name: 'Poor (below 650)' }
],
defaultValue: 'good',
tooltip: 'Typical rates shown are based on credit score'
});
});
loanSection.addRow(row => {
row.addTextPanel('rateGuide', {
computedValue: () => {
const credit = loanSection.dropdown('creditScore')?.value() || 'good';
const condition = vehicleSection.dropdown('condition')?.value() || 'new';
const rateRanges: Record<string, Record<string, string>> = {
'new': {
'excellent': 'Typical rate: 4.0% - 5.5%',
'good': 'Typical rate: 5.5% - 7.5%',
'fair': 'Typical rate: 8.0% - 12.0%',
'poor': 'Typical rate: 12.0% - 18.0%'
},
'certified': {
'excellent': 'Typical rate: 4.5% - 6.0%',
'good': 'Typical rate: 6.0% - 8.5%',
'fair': 'Typical rate: 9.0% - 13.0%',
'poor': 'Typical rate: 13.0% - 20.0%'
},
'used': {
'excellent': 'Typical rate: 5.5% - 7.0%',
'good': 'Typical rate: 7.0% - 10.0%',
'fair': 'Typical rate: 10.0% - 15.0%',
'poor': 'Typical rate: 15.0% - 24.0%'
}
};
return rateRanges[condition]?.[credit] || 'Rate varies by lender';
},
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Calculation Breakdown Section
const breakdownSection = form.addSubform('breakdown', { title: '📊 Cost Breakdown', isCollapsible: true });
breakdownSection.addRow(row => {
row.addPriceDisplay('taxesAndFees', {
label: 'Total Taxes & Fees',
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
return Math.round((salesTax + docFee + regFee + otherFees) * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('tradeInEquity', {
label: 'Trade-in Equity',
computedValue: () => {
const tradeIn = vehicleSection.money('tradeIn')?.value() || 0;
const payoff = vehicleSection.money('tradeInPayoff')?.value() || 0;
return tradeIn - payoff;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('amountFinanced', {
label: 'Amount Financed',
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const downPayment = vehicleSection.money('downPayment')?.value() || 5000;
const tradeIn = vehicleSection.money('tradeIn')?.value() || 0;
const payoff = vehicleSection.money('tradeInPayoff')?.value() || 0;
const rollInFees = feesSection.checkbox('rollInFees')?.value();
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
const totalFees = salesTax + docFee + regFee + otherFees;
const tradeEquity = tradeIn - payoff;
let financed = vehiclePrice - downPayment - tradeEquity;
if (rollInFees) financed += totalFees;
return Math.max(Math.round(financed * 100) / 100, 0);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('totalInterest', {
label: 'Total Interest',
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const downPayment = vehicleSection.money('downPayment')?.value() || 5000;
const tradeIn = vehicleSection.money('tradeIn')?.value() || 0;
const payoff = vehicleSection.money('tradeInPayoff')?.value() || 0;
const rollInFees = feesSection.checkbox('rollInFees')?.value();
const interestRate = loanSection.decimal('interestRate')?.value() || 6.5;
const term = parseInt(loanSection.dropdown('loanTerm')?.value() || '60');
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
const totalFees = salesTax + docFee + regFee + otherFees;
const tradeEquity = tradeIn - payoff;
let principal = vehiclePrice - downPayment - tradeEquity;
if (rollInFees) principal += totalFees;
principal = Math.max(principal, 0);
const monthlyRate = interestRate / 100 / 12;
if (monthlyRate === 0) return 0;
const monthlyPayment = principal * (monthlyRate * Math.pow(1 + monthlyRate, term)) / (Math.pow(1 + monthlyRate, term) - 1);
const totalPaid = monthlyPayment * term;
return Math.round((totalPaid - principal) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
// Payment Section
const paymentSection = form.addSubform('payment', { title: '💰 Your Payment', isCollapsible: false });
paymentSection.addRow(row => {
row.addPriceDisplay('monthlyPayment', {
label: 'Monthly Payment',
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const downPayment = vehicleSection.money('downPayment')?.value() || 5000;
const tradeIn = vehicleSection.money('tradeIn')?.value() || 0;
const payoff = vehicleSection.money('tradeInPayoff')?.value() || 0;
const rollInFees = feesSection.checkbox('rollInFees')?.value();
const interestRate = loanSection.decimal('interestRate')?.value() || 6.5;
const term = parseInt(loanSection.dropdown('loanTerm')?.value() || '60');
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
const totalFees = salesTax + docFee + regFee + otherFees;
const tradeEquity = tradeIn - payoff;
let principal = vehiclePrice - downPayment - tradeEquity;
if (rollInFees) principal += totalFees;
principal = Math.max(principal, 0);
if (principal === 0) return 0;
const monthlyRate = interestRate / 100 / 12;
if (monthlyRate === 0) return Math.round((principal / term) * 100) / 100;
const monthlyPayment = principal * (monthlyRate * Math.pow(1 + monthlyRate, term)) / (Math.pow(1 + monthlyRate, term) - 1);
return Math.round(monthlyPayment * 100) / 100;
},
variant: 'large'
});
});
paymentSection.addRow(row => {
row.addPriceDisplay('totalCost', {
label: 'Total Cost of Vehicle',
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const downPayment = vehicleSection.money('downPayment')?.value() || 5000;
const tradeIn = vehicleSection.money('tradeIn')?.value() || 0;
const payoff = vehicleSection.money('tradeInPayoff')?.value() || 0;
const rollInFees = feesSection.checkbox('rollInFees')?.value();
const interestRate = loanSection.decimal('interestRate')?.value() || 6.5;
const term = parseInt(loanSection.dropdown('loanTerm')?.value() || '60');
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
const totalFees = salesTax + docFee + regFee + otherFees;
const tradeEquity = tradeIn - payoff;
let principal = vehiclePrice - downPayment - tradeEquity;
if (rollInFees) principal += totalFees;
principal = Math.max(principal, 0);
const monthlyRate = interestRate / 100 / 12;
let totalPaid = principal;
if (monthlyRate > 0 && principal > 0) {
const monthlyPayment = principal * (monthlyRate * Math.pow(1 + monthlyRate, term)) / (Math.pow(1 + monthlyRate, term) - 1);
totalPaid = monthlyPayment * term;
}
// Add down payment and fees paid upfront
totalPaid += downPayment;
if (!rollInFees) totalPaid += totalFees;
return Math.round(totalPaid * 100) / 100;
},
variant: 'success'
}, '1fr');
row.addPriceDisplay('dueAtSigning', {
label: 'Due at Signing',
computedValue: () => {
const downPayment = vehicleSection.money('downPayment')?.value() || 5000;
const rollInFees = feesSection.checkbox('rollInFees')?.value();
if (rollInFees) return downPayment;
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const taxRate = feesSection.decimal('salesTaxRate')?.value() || 6.5;
const docFee = feesSection.money('docFee')?.value() || 300;
const regFee = feesSection.money('registrationFee')?.value() || 200;
const otherFees = feesSection.money('otherFees')?.value() || 0;
const salesTax = vehiclePrice * (taxRate / 100);
return Math.round((downPayment + salesTax + docFee + regFee + otherFees) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const vehiclePrice = vehicleSection.money('vehiclePrice')?.value() || 35000;
const term = loanSection.dropdown('loanTerm')?.value() || '60';
const rate = loanSection.decimal('interestRate')?.value() || 6.5;
const termLabels: Record<string, string> = {
'24': '2 years', '36': '3 years', '48': '4 years',
'60': '5 years', '72': '6 years', '84': '7 years'
};
return `$${vehiclePrice.toLocaleString()} vehicle | ${termLabels[term]} | ${rate}% APR`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Estimates are for informational purposes only. Actual rates and payments may vary by lender.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Get Pre-Approved'
});
}