export function carLoanCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Auto Loan Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Vehicle & Loan Section
const loanSection = form.addSubform('loanDetails', { title: '๐ Loan Details' });
loanSection.addRow(row => {
row.addDecimal('vehiclePrice', {
label: 'Vehicle Price ($)',
min: 1000,
max: 500000,
defaultValue: 35000,
decimalPlaces: 0,
isRequired: true
}, '1fr');
row.addDecimal('downPayment', {
label: 'Down Payment ($)',
min: 0,
max: 500000,
defaultValue: 5000,
decimalPlaces: 0
}, '1fr');
});
loanSection.addRow(row => {
row.addDecimal('tradeInValue', {
label: 'Trade-In Value ($)',
min: 0,
max: 100000,
defaultValue: 0,
decimalPlaces: 0
}, '1fr');
row.addDecimal('salesTaxRate', {
label: 'Sales Tax Rate (%)',
min: 0,
max: 15,
defaultValue: 7,
decimalPlaces: 2
}, '1fr');
});
// Financing Section
const financeSection = form.addSubform('financeDetails', { title: '๐ Financing Terms' });
financeSection.addRow(row => {
row.addDecimal('interestRate', {
label: 'Interest Rate (APR %)',
min: 0,
max: 30,
defaultValue: 6.5,
decimalPlaces: 2,
isRequired: true
}, '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');
});
financeSection.addRow(row => {
row.addDropdown('creditScore', {
label: 'Credit Score Range',
options: [
{ id: 'excellent', name: 'Excellent (750+)' },
{ id: 'good', name: 'Good (700-749)' },
{ id: 'fair', name: 'Fair (650-699)' },
{ id: 'poor', name: 'Poor (600-649)' },
{ id: 'bad', name: 'Bad (Below 600)' }
],
defaultValue: 'good',
tooltip: 'Credit score affects your actual rate. This is for reference.'
}, '1fr');
});
// Additional Costs Section
const additionalSection = form.addSubform('additionalCosts', { title: '๐ Additional Costs' });
additionalSection.addRow(row => {
row.addDecimal('docFees', {
label: 'Documentation Fees ($)',
min: 0,
max: 2000,
defaultValue: 300,
decimalPlaces: 0
}, '1fr');
row.addDecimal('registrationFees', {
label: 'Registration & Title ($)',
min: 0,
max: 1000,
defaultValue: 200,
decimalPlaces: 0
}, '1fr');
});
additionalSection.addRow(row => {
row.addCheckbox('includeGap', {
label: 'GAP Insurance (+$500)',
defaultValue: false
}, '1fr');
row.addCheckbox('includeWarranty', {
label: 'Extended Warranty (+$1,500)',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Results Section
const resultsSection = form.addSubform('results', { title: '๐ฐ Loan Summary', isCollapsible: false });
const calculateLoanAmount = () => {
const price = loanSection.decimal('vehiclePrice')?.value() || 35000;
const down = loanSection.decimal('downPayment')?.value() || 0;
const tradeIn = loanSection.decimal('tradeInValue')?.value() || 0;
const taxRate = (loanSection.decimal('salesTaxRate')?.value() || 7) / 100;
const taxableAmount = price - tradeIn;
const salesTax = taxableAmount * taxRate;
const docFees = additionalSection.decimal('docFees')?.value() || 0;
const regFees = additionalSection.decimal('registrationFees')?.value() || 0;
let additional = docFees + regFees;
if (additionalSection.checkbox('includeGap')?.value()) additional += 500;
if (additionalSection.checkbox('includeWarranty')?.value()) additional += 1500;
return price + salesTax + additional - down - tradeIn;
};
const calculateMonthlyPayment = () => {
const principal = calculateLoanAmount();
const annualRate = (financeSection.decimal('interestRate')?.value() || 6.5) / 100;
const monthlyRate = annualRate / 12;
const months = parseInt(financeSection.dropdown('loanTerm')?.value() || '60');
if (monthlyRate === 0) {
return principal / months;
}
const payment = principal * (monthlyRate * Math.pow(1 + monthlyRate, months)) /
(Math.pow(1 + monthlyRate, months) - 1);
return payment;
};
resultsSection.addRow(row => {
row.addPriceDisplay('loanAmount', {
label: 'Total Loan Amount',
computedValue: () => Math.round(calculateLoanAmount()),
variant: 'default'
}, '1fr');
row.addPriceDisplay('salesTax', {
label: 'Sales Tax',
computedValue: () => {
const price = loanSection.decimal('vehiclePrice')?.value() || 35000;
const tradeIn = loanSection.decimal('tradeInValue')?.value() || 0;
const taxRate = (loanSection.decimal('salesTaxRate')?.value() || 7) / 100;
return Math.round((price - tradeIn) * taxRate);
},
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('totalInterest', {
label: 'Total Interest Paid',
computedValue: () => {
const monthly = calculateMonthlyPayment();
const months = parseInt(financeSection.dropdown('loanTerm')?.value() || '60');
const principal = calculateLoanAmount();
return Math.round(monthly * months - principal);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('totalCost', {
label: 'Total Cost of Loan',
computedValue: () => {
const monthly = calculateMonthlyPayment();
const months = parseInt(financeSection.dropdown('loanTerm')?.value() || '60');
return Math.round(monthly * months);
},
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addTextPanel('rateDisclaimer', {
computedValue: () => {
const credit = financeSection.dropdown('creditScore')?.value() || 'good';
const rateRanges: Record<string, string> = {
'excellent': 'With excellent credit, you may qualify for rates as low as 3-5%.',
'good': 'Good credit typically qualifies for rates between 5-7%.',
'fair': 'Fair credit usually means rates between 7-12%.',
'poor': 'Poor credit may result in rates between 12-18%.',
'bad': 'Bad credit often means rates above 18% or requiring a cosigner.'
};
return rateRanges[credit] || '';
},
customStyles: { 'font-size': '0.9rem', 'color': '#059669' }
});
});
const finalSection = form.addSubform('final', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('monthlyPayment', {
label: 'Monthly Payment',
computedValue: () => Math.round(calculateMonthlyPayment()),
variant: 'large',
suffix: '/month'
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Get pre-approved for accurate rates.',
customStyles: { 'font-size': '0.85rem', 'color': '#94a3b8', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Get Pre-Approved'
});
}