import React, { useState, useEffect, useRef } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import Chart from "https://esm.sh/chart.js/auto";
interface Offer {
id: string;
lender: string;
rate: number;
term: number;
closingCosts: number;
monthlyPayment: number;
totalInterest: number;
}
function App() {
const [offers, setOffers] = useState<Offer[]>([]);
const [newOffer, setNewOffer] = useState<Omit<Offer, 'id' | 'monthlyPayment' | 'totalInterest'>>({
lender: "",
rate: 6,
term: 30,
closingCosts: 0,
});
const [loanAmount, setLoanAmount] = useState(200000);
const [selectedOffer, setSelectedOffer] = useState<Offer | null>(null);
const monthlyPaymentChartRef = useRef<Chart | null>(null);
const principalInterestChartRef = useRef<Chart | null>(null);
useEffect(() => {
fetchOffers();
}, []);
useEffect(() => {
if (offers.length > 0) {
updateMonthlyPaymentChart();
setSelectedOffer(offers[0]);
} else {
setSelectedOffer(null);
}
}, [offers]);
useEffect(() => {
if (selectedOffer) {
updatePrincipalInterestChart();
}
}, [selectedOffer]);
const fetchOffers = async () => {
try {
const response = await fetch("/offers");
if (response.ok) {
const data = await response.json();
const validOffers = data.filter((offer: any) =>
offer.id && offer.lender && typeof offer.rate === 'number' &&
typeof offer.term === 'number' && typeof offer.closingCosts === 'number' &&
typeof offer.monthlyPayment === 'number' && typeof offer.totalInterest === 'number'
);
setOffers(validOffers);
} else {
console.error("Failed to fetch offers");
}
} catch (error) {
console.error("Error fetching offers:", error);
}
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setNewOffer((prev) => ({ ...prev, [name]: name === "lender" ? value : Number(value) }));
};
const calculateMonthlyPayment = (principal: number, annualRate: number, termYears: number) => {
const monthlyRate = annualRate / 100 / 12;
const numPayments = termYears * 12;
return (principal * monthlyRate * Math.pow(1 + monthlyRate, numPayments)) / (Math.pow(1 + monthlyRate, numPayments) - 1);
};
const calculateTotalInterest = (monthlyPayment: number, termYears: number, principal: number) => {
return (monthlyPayment * termYears * 12) - principal;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const monthlyPayment = calculateMonthlyPayment(loanAmount, newOffer.rate, newOffer.term);
const totalInterest = calculateTotalInterest(monthlyPayment, newOffer.term, loanAmount);
const offerWithCalculations = {
...newOffer,
monthlyPayment,
totalInterest,
};
try {
const response = await fetch("/offers", {
method: "POST",
headers: { "Content-Type": "application/json" },