Skip to content

Commit

Permalink
Exclude IRA rebates; add ability to show generic info about HEAR/HER
Browse files Browse the repository at this point in the history
## Description

This excludes all federal non-tax-credit incentives that come from the
API, and adds in these visually-distinct cards with less-specific info
about HEAR rebates if the API response indicates the user is below
150% AMI.

One slight difference from the design spec is that the description
text is grey-500, rather than 400, which fails the a11y test for not
having enough contrast with the yellow background. I can't even see
the difference at a glance, so I think it's fine. (As a drive-by, I
fixed a couple places where we had `gray` instead of `grey`.)

Once we settle on copy, I'll start the translation workflow.

We don't have any state-specific logic yet, but there's a clear place
to add it once we figure out what exactly we want for each state. Some
states will want us to show nothing at all (either because they don't
want to commit to anything or because they already have actual HEAR
programs represented in the API), some states may want semi-specific
info in advance of rolling out actual programs, some may tell us
they're going to exclude certain items, etc. All that can be built on
this foundation.

As background, I don't want to put this in the API because the kind of
info we want for HEAR just doesn't fit within the current API shape:
it's too vague and uncertain. I don't want to extend the API shape to
encompass stuff like this because I think it's valuable, on principle,
to hold the line that the API only returns concrete, actionable
incentives that are certain, or close to certain, to be available.

https://app.asana.com/0/1206661332626418/1206925887004341

## Test Plan

Cypress tests pass.
  • Loading branch information
oyamauchi committed Apr 24, 2024
1 parent 27ea32c commit 15402dc
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 90 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/state-calculator.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('rewiring-america-state-calculator', () => {

cy.get('rewiring-america-state-calculator')
.shadow()
.contains('$8,000 off a heat pump');
.contains('Discount off a heat pump');

cy.get('rewiring-america-state-calculator')
.shadow()
Expand Down
1 change: 1 addition & 0 deletions src/api/calculator-types-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ export interface APIResponse {
};
location: APILocation;
incentives: Incentive[];
is_under_150_ami: boolean;
}
54 changes: 33 additions & 21 deletions src/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,48 @@ import { PropsWithChildren, forwardRef } from 'react';

import clsx from 'clsx';

export enum CardStyle {
NORMAL,
HIGHLIGHTED,
FLAT,
}

/**
* Renders a padded card with white background and drop shadow. "isFlat" uses
* a yellow background and no shadow instead. Children are placed in a
* 1-column grid.
*/
export const Card = forwardRef<
HTMLDivElement,
PropsWithChildren<{ id?: string; isFlat?: boolean }>
>(({ id, isFlat, children }, ref) => (
<div
ref={ref}
id={id}
className={clsx(
'rounded-xl',
'min-w-52',
isFlat && 'bg-yellow-200',
!isFlat && 'bg-white shadow',
)}
>
PropsWithChildren<{ id?: string; cardStyle?: CardStyle }>
>(({ id, cardStyle, children }, ref) => {
const style = cardStyle ?? CardStyle.NORMAL;
return (
<div
ref={ref}
id={id}
className={clsx(
'grid',
'grid-cols-1',
'gap-4',
isFlat && 'mx-auto text-center max-w-78',
isFlat && 'px-4 py-8',
!isFlat && 'p-4 sm:p-6',
'rounded-xl',
'min-w-52',
style === CardStyle.FLAT && 'bg-yellow-200',
style !== CardStyle.FLAT && 'shadow',
style === CardStyle.NORMAL && 'bg-white',
style === CardStyle.HIGHLIGHTED &&
'bg-yellow-100 border border-yellow-500',
)}
>
{children}
<div
className={clsx(
'grid',
'grid-cols-1',
'gap-4',
style === CardStyle.FLAT && 'mx-auto text-center max-w-78',
style === CardStyle.FLAT && 'px-4 py-8',
style !== CardStyle.FLAT && 'p-4 sm:p-6',
)}
>
{children}
</div>
</div>
</div>
));
);
});
11 changes: 11 additions & 0 deletions src/i18n/strings/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,15 @@ export const templates = {
sfc7214f623fe475d: `Selecciona la empresa a la que paga su factura de electricidad.`,
sfe16afc784bb9d76: `Tejado solar`,
sfe81d5d73a35a2cf: `Calcular`,
sb1ef6ac20f1ddfff: `Discount off an electric panel`,
sf8b5deb9ea9f5054: `Discount off an electric stove`,
sae2ffd247e500180: `Discount off electric wiring`,
s9de4186c3f39ea44: `Discount off a heat pump water heater`,
s2b1b3dc2f8da1ce4: `Discount off a heat pump`,
s635e3d7c474426ce: `Discount off a heat pump clothes dryer`,
s1cc63fbd986ae5d9: `Discount off weatherization`,
s1e73057deee4510e: `However, rebates will be implemented differently in each state, so we cannot guarantee final amounts, eligibility, or timeline.`,
sb3615709fedc9d4d: `Federal Home Electrification and Appliance Rebates (HEAR)`,
scc19aa488a295dfd: str`The federal guidelines allot a discount of up to \$${0}.`,
sca61f9664c0f6099: `https://homes.rewiringamerica.org/federal-incentives/home-electrification-appliance-rebates`,
};
74 changes: 74 additions & 0 deletions src/ira-rebates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { str } from './i18n/str';
import { MsgFn } from './i18n/use-translated';
import { Project } from './projects';

export type IRARebate = {
project: Project;
headline: string;
program: string;
description: string;
url: string;
};

const hearRebates: {
project: Project;
getHeadline: (msg: MsgFn) => string;
maxAmount: number;
}[] = [
{
project: 'wiring',
getHeadline: msg => msg('Discount off an electric panel'),
maxAmount: 4000,
},
{
project: 'cooking',
getHeadline: msg => msg('Discount off an electric stove'),
maxAmount: 840,
},
{
project: 'wiring',
getHeadline: msg => msg('Discount off electric wiring'),
maxAmount: 2500,
},
{
project: 'heat_pump_water_heater',
getHeadline: msg => msg('Discount off a heat pump water heater'),
maxAmount: 1750,
},
{
project: 'hvac',
getHeadline: msg => msg('Discount off a heat pump'),
maxAmount: 8000,
},
{
project: 'heat_pump_clothes_dryer',
getHeadline: msg => msg('Discount off a heat pump clothes dryer'),
maxAmount: 840,
},
{
project: 'weatherization_and_efficiency',
getHeadline: msg => msg('Discount off weatherization'),
maxAmount: 1600,
},
];

/* @ts-expect-error(6133) we will condition logic on state in future. */
export function getRebatesFor(state: string, msg: MsgFn): IRARebate[] {
const disclaimerText = msg(
'However, rebates will be implemented differently in each state, so we cannot guarantee final amounts, eligibility, or timeline.',
);
return hearRebates.map(rebate => ({
project: rebate.project,
headline: rebate.getHeadline(msg),
program: msg('Federal Home Electrification and Appliance Rebates (HEAR)'),
description:
msg(
str`The federal guidelines allot a discount of up to $${rebate.maxAmount.toLocaleString()}.`,
) +
' ' +
disclaimerText,
url: msg(
'https://homes.rewiringamerica.org/federal-incentives/home-electrification-appliance-rebates',
),
}));
}
Loading

0 comments on commit 15402dc

Please sign in to comment.