Add household calculator tab#24
Merged
Merged
Conversation
Add a household calculator view alongside the existing map. Users enter state, filing status, ages, earnings, optional other income, and per-child ages, then see federal EITC, federal CTC, state EITC, state CTC, and the total. Calculations go live to the PolicyEngine US API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the explicit filing-status pill group with an "Add spouse" toggle. Filing status is now derived: spouse -> JOINT, no spouse + children -> HEAD_OF_HOUSEHOLD, otherwise SINGLE. Remove the optional other-income field. Add the PolicyEngine favicon at public/favicon.svg to match the path already referenced in layout.tsx metadata. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ctc variable in PolicyEngine US is the gross credit before tax-liability and refundability limits, which overstated the credit for low-earnings households (e.g. $4,400 shown for a household with $0 earnings, where the actual received amount is $0). Request and read ctc_value instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The API returns result.tax_units.tax_unit.<var>, not result.household.tax_units.tax_unit.<var>. The extra .household lookup meant every variable resolved to undefined and the calculator displayed 0 for all credits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the "Add spouse" button with an "Are you married?" checkbox placed directly below State. When checked, spouse age renders next to primary age and spouse earnings next to primary earnings in a two-column row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Children render as cards in a 3-per-row grid, wrapping to a new row beyond three. Each card stacks the age input and a small Remove button. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Show a Plotly line chart with federal/state EITC and CTC curves plotted against earnings (~17 sample points from $0 to $200k). The user's submitted earnings is marked with a dashed vertical line. While the API sweep is in flight, the results panel shows a teal spinner and the submit button shows an inline mini-spinner. Adds react-plotly.js + plotly.js-dist-min as deps. Plotly is loaded via next/dynamic with ssr:false to avoid window-not-defined on render. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use the multi-series palette from @policyengine/design-system (#319795, #285E61, #0EA5E9, #026AA2), Inter throughout at the prescribed sizes (14px axis, 12px ticks), gray.200 (#E2E8F0) gridlines, black text on white, sentence-case title, and add the PolicyEngine teal logo as a bottom-right watermark. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the 17-call parallel sweep with a single vectorized API call using the household.axes parameter, matching policyengine-app's EarningsVariation approach. Now plots 401 sample points from $0 to max(200k, 2*current_earnings) in one round-trip — both faster (one HTTP call) and visibly smoother. Switch the line shape from spline to linear since the dense sampling makes the curves smooth on their own and avoids spline overshoot at EITC plateau corners. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror BaselineOnlyChart from policyengine-app: drop the in-chart title (now rendered as an H3 above the plot), shrink the top margin, position the legend at y=1.15 in the freed space, use per-line hovertemplates with "If you earn X, your <credit> is Y" copy, replace the dashed vertical "Your earnings" marker with a small dot on each line at the current earnings (interpolated), and use rgba(0,0,0,0) plot background per plotLayoutFont. Eliminates the title/legend overlap visible in the previous version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Draw a dashed gray vertical line at the user's current earnings, with a small label anchored inside the plot area at y=0.97 (below the legend at 1.15) so it doesn't overlap legend or title. The dots on each line at the current earnings are kept too — they show the credit amount per series at the user's earnings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add an effect that resets the calculation result, sweep data, and error whenever any form input changes. Removes the stale-looking state where the user has tweaked a field but the panel still shows the previous calculation, until they click Calculate again. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Total Investment / Poverty Reduction / Child Poverty Reduction metrics are aggregate state-level stats relevant only to the map view. Render the banner only when appView is "map". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Place a Tax year dropdown (2024, 2025, 2026) to the right of the State dropdown in a 2-column row. Year is now local to the calculator and initialized from the App-level year prop so the two views can be set independently. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add matching legendgroup on each line+dot pair so clicking a legend entry hides both the line and the "you are here" marker dot together. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pin the x-axis range to [0, max(earnings)] so the chart's left edge sits exactly at $0 with no padding. The y-axis already had rangemode: "tozero". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI runs bun install --frozen-lockfile; previous plotly install via npm updated package.json without touching bun.lock, which would have failed the install step on CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
api.policyengine.org/us/calculate— no precomputed data needed.Files
frontend/src/api/policyengine.ts— household JSON builder + API clientfrontend/src/components/HouseholdCalculator.tsx— form + results cardfrontend/src/App.tsx— tab toggle between Map and CalculatorTest plan
npm run dev, switch to Household calculator tabnpm run buildpasses🤖 Generated with Claude Code