import { calculatePaycheck, annualizeFromHourly, PAY_FREQUENCIES } from "./paycheckEngine.mjs"; import { FEDERAL_TAX_DATA } from "../data/federalTaxData.mjs"; import { STATES_TAX_DATA } from "../data/statesTaxData.mjs"; import { formatUSD as fmtUSD, formatUSD2, formatPct } from "./format.mjs"; function init() { const root = document.querySelector("[data-paycheck-calc]"); if (!root) return; const stateSlug = root.dataset.state; const stateConfig = STATES_TAX_DATA[stateSlug]; if (!stateConfig) return; const payTypeEl = root.querySelector("#payType"); const grossEl = root.querySelector("#grossAmount"); const hoursRow = root.querySelector("#hoursRow"); const hoursEl = root.querySelector("#hoursPerWeek"); const frequencyEl = root.querySelector("#payFrequency"); const filingEl = root.querySelector("#filingStatus"); const els = { netPerPeriod: root.querySelector("#out-netPerPeriod"), netPerPeriodLabel: root.querySelector("#out-netPerPeriodLabel"), grossAnnual: root.querySelector("#out-grossAnnual"), federalTax: root.querySelector("#out-federalTax"), stateTax: root.querySelector("#out-stateTax"), stateTaxRow: root.querySelector("#out-stateTaxRow"), socialSecurity: root.querySelector("#out-socialSecurity"), medicare: root.querySelector("#out-medicare"), netAnnual: root.querySelector("#out-netAnnual"), effectiveRate: root.querySelector("#out-effectiveRate"), }; function getGrossAnnual() { const raw = parseFloat(grossEl.value) || 0; if (payTypeEl.value === "hourly") { const hours = parseFloat(hoursEl.value) || 0; return annualizeFromHourly(raw, hours, 52); } return raw; } function render() { const grossAnnual = getGrossAnnual(); const filingStatus = filingEl.value; const payFrequency = frequencyEl.value; const result = calculatePaycheck({ grossAnnual, filingStatus, payFrequency, federalConfig: FEDERAL_TAX_DATA, stateConfig, }); els.netPerPeriod.textContent = formatUSD2(result.netPerPeriod); els.netPerPeriodLabel.textContent = `net per ${PAY_FREQUENCIES[payFrequency].label.toLowerCase()} paycheck`; els.grossAnnual.textContent = fmtUSD(result.grossAnnual); els.federalTax.textContent = fmtUSD(result.federal.tax); if (stateConfig.type === "none") { els.stateTaxRow.style.display = "none"; } else { els.stateTaxRow.style.display = ""; els.stateTax.textContent = fmtUSD(result.state.tax); } els.socialSecurity.textContent = fmtUSD(result.fica.socialSecurity); els.medicare.textContent = fmtUSD(result.fica.medicare + result.fica.additionalMedicare); els.netAnnual.textContent = fmtUSD(result.netAnnual); els.effectiveRate.textContent = formatPct(result.effectiveRate); } function onPayTypeChange() { const isHourly = payTypeEl.value === "hourly"; hoursRow.style.display = isHourly ? "" : "none"; grossEl.previousElementSibling.textContent = isHourly ? "Hourly rate" : "Gross annual salary"; render(); } [grossEl, hoursEl, frequencyEl, filingEl].forEach((el) => el.addEventListener("input", render)); payTypeEl.addEventListener("change", onPayTypeChange); const stateSwitcher = root.querySelector("#stateSwitcher"); if (stateSwitcher) { stateSwitcher.addEventListener("change", (e) => { const target = e.target.value; if (target) window.location.href = `/finance/paycheck-calculator/${target}/`; }); } render(); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); }