@aclymatepackages/modules 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/babel.config.json +18 -0
- package/dist/components/CompaniesAutocomplete.js +126 -0
- package/dist/components/CompanyOnboardingInput.js +116 -0
- package/dist/components/ComparisonChart.js +200 -0
- package/dist/components/CustomTooltipDisplayRow.js +59 -0
- package/dist/components/EmissionsChart.js +467 -0
- package/dist/components/EmissionsCustomTooltip.js +181 -0
- package/dist/components/EmissionsPieChart.js +130 -0
- package/dist/components/EmissionsReductionGraph.js +118 -0
- package/dist/components/FootprintEquivalencies.js +181 -0
- package/dist/components/FootprintVideo.js +262 -0
- package/dist/components/FuelTypesSelect.js +36 -0
- package/dist/components/IndustryAutocomplete.js +58 -0
- package/dist/components/PlacesAutocomplete.js +173 -0
- package/dist/components/StripeElements.js +95 -0
- package/dist/components/YesNoQuestion.js +88 -0
- package/dist/components/stripeInput.js +293 -0
- package/dist/components/useChartWarningLabels.js +143 -0
- package/dist/index.js +118 -0
- package/package.json +74 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +43 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/components/CompaniesAutocomplete.js +125 -0
- package/src/components/CompanyOnboardingInput.js +113 -0
- package/src/components/ComparisonChart.js +236 -0
- package/src/components/CustomTooltipDisplayRow.js +41 -0
- package/src/components/EmissionsChart.js +579 -0
- package/src/components/EmissionsCustomTooltip.js +146 -0
- package/src/components/EmissionsPieChart.js +120 -0
- package/src/components/EmissionsReductionGraph.js +107 -0
- package/src/components/FootprintEquivalencies.js +203 -0
- package/src/components/FootprintVideo.js +328 -0
- package/src/components/FuelTypesSelect.js +29 -0
- package/src/components/IndustryAutocomplete.js +56 -0
- package/src/components/PlacesAutocomplete.js +174 -0
- package/src/components/StripeElements.js +95 -0
- package/src/components/YesNoQuestion.js +68 -0
- package/src/components/stripeInput.js +288 -0
- package/src/components/useChartWarningLabels.js +139 -0
- package/src/index.js +35 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Tooltip as ChartTooltip,
|
|
5
|
+
ResponsiveContainer,
|
|
6
|
+
PieChart,
|
|
7
|
+
Pie,
|
|
8
|
+
Cell,
|
|
9
|
+
} from "recharts";
|
|
10
|
+
|
|
11
|
+
import { Typography, Grid, Avatar } from "@mui/material";
|
|
12
|
+
|
|
13
|
+
import { DefaultPaper } from "@aclymatepackages/atoms";
|
|
14
|
+
import { formatDecimal } from "@aclymatepackages/formatters";
|
|
15
|
+
import { sumTonsCo2e } from "@aclymatepackages/other-helpers";
|
|
16
|
+
import {
|
|
17
|
+
buildSubcategoriesArray,
|
|
18
|
+
buildScopesArray,
|
|
19
|
+
} from "@aclymatepackages/subcategories";
|
|
20
|
+
|
|
21
|
+
const PieChartCustomTooltip = ({ payload: passedPayload }) => {
|
|
22
|
+
const [payloadObj] = passedPayload;
|
|
23
|
+
const { payload = {} } = payloadObj || [{}];
|
|
24
|
+
const { name, emissionPercentage, color, icon, Icon } = payload;
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<DefaultPaper>
|
|
28
|
+
<Grid container spacing={2} alignItems="center">
|
|
29
|
+
<Grid item>
|
|
30
|
+
<Avatar style={{ backgroundColor: color, color: "white" }}>
|
|
31
|
+
{icon}
|
|
32
|
+
{Icon && <Icon style={{ color: "inherit" }} />}
|
|
33
|
+
</Avatar>
|
|
34
|
+
</Grid>
|
|
35
|
+
<Grid item>
|
|
36
|
+
<Typography variant="subtitle1" color="textPrimary">
|
|
37
|
+
{name}
|
|
38
|
+
</Typography>
|
|
39
|
+
<Typography variant="caption" color="textSecondary">{`${formatDecimal(
|
|
40
|
+
emissionPercentage
|
|
41
|
+
)}% of total emissions`}</Typography>
|
|
42
|
+
</Grid>
|
|
43
|
+
</Grid>
|
|
44
|
+
</DefaultPaper>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const EmissionsPieChart = ({
|
|
49
|
+
dataArray: emissions,
|
|
50
|
+
viewMode = "subcategories",
|
|
51
|
+
pieChartRef,
|
|
52
|
+
}) => {
|
|
53
|
+
const subcategoriesArray = buildSubcategoriesArray(emissions);
|
|
54
|
+
const scopesArray = buildScopesArray();
|
|
55
|
+
|
|
56
|
+
const emissionsSum = sumTonsCo2e(emissions);
|
|
57
|
+
|
|
58
|
+
const formatChartPieSlices = () => {
|
|
59
|
+
const filterFunction = (subcategory) => (emission) => {
|
|
60
|
+
if (viewMode === "subcategories") {
|
|
61
|
+
return emission.subcategory === subcategory;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const scopeNumber = Number(subcategory.charAt(subcategory.length - 1));
|
|
65
|
+
return emission.scope === scopeNumber;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const slicesArray =
|
|
69
|
+
viewMode === "subcategories" ? subcategoriesArray : scopesArray;
|
|
70
|
+
|
|
71
|
+
const unProjectedSlices = slicesArray.filter(({ subcategory }) => {
|
|
72
|
+
const projectedStringArray = subcategory.split("_");
|
|
73
|
+
return projectedStringArray.length === 1;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return unProjectedSlices.map((subcategoryObj) => {
|
|
77
|
+
const { subcategory } = subcategoryObj;
|
|
78
|
+
const emissionsWithThisCategory = emissions.filter(
|
|
79
|
+
filterFunction(subcategory)
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const categoryEmissionsSum = sumTonsCo2e(emissionsWithThisCategory);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
...subcategoryObj,
|
|
86
|
+
emissionPercentage: (categoryEmissionsSum / emissionsSum) * 100,
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const pieSlicesWithPercentages = formatChartPieSlices();
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<ResponsiveContainer height="100%" aspect={1.5}>
|
|
95
|
+
<PieChart ref={pieChartRef}>
|
|
96
|
+
<Pie
|
|
97
|
+
data={pieSlicesWithPercentages}
|
|
98
|
+
outerRadius={"100%"}
|
|
99
|
+
fill="#8884d8"
|
|
100
|
+
dataKey="emissionPercentage"
|
|
101
|
+
cx="50%"
|
|
102
|
+
cy="50%"
|
|
103
|
+
>
|
|
104
|
+
{pieSlicesWithPercentages.map(({ category, name, color }) => (
|
|
105
|
+
<Cell
|
|
106
|
+
key={`emissions-pie-chart-cell-${category}`}
|
|
107
|
+
name={name}
|
|
108
|
+
fill={color}
|
|
109
|
+
/>
|
|
110
|
+
))}
|
|
111
|
+
</Pie>
|
|
112
|
+
<ChartTooltip
|
|
113
|
+
wrapperStyle={{ zIndex: 99 }}
|
|
114
|
+
content={<PieChartCustomTooltip />}
|
|
115
|
+
/>
|
|
116
|
+
</PieChart>
|
|
117
|
+
</ResponsiveContainer>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
export default EmissionsPieChart;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { Box, Typography } from "@mui/material";
|
|
4
|
+
import { useTheme } from "@mui/styles";
|
|
5
|
+
import {
|
|
6
|
+
ResponsiveContainer,
|
|
7
|
+
LineChart,
|
|
8
|
+
Line,
|
|
9
|
+
XAxis,
|
|
10
|
+
YAxis,
|
|
11
|
+
CartesianGrid,
|
|
12
|
+
Tooltip,
|
|
13
|
+
} from "recharts";
|
|
14
|
+
|
|
15
|
+
import { calculateEmissionsDecayRate } from "@aclymatepackages/other-helpers";
|
|
16
|
+
|
|
17
|
+
const CustomTooltip = ({ active, payload, label }) => {
|
|
18
|
+
if (active && payload && payload.length) {
|
|
19
|
+
const { remainingAmount } = payload[0].payload;
|
|
20
|
+
return (
|
|
21
|
+
<Box
|
|
22
|
+
style={{
|
|
23
|
+
background: "#fff",
|
|
24
|
+
border: "1px solid #ccc",
|
|
25
|
+
padding: "10px",
|
|
26
|
+
borderRadius: "5px",
|
|
27
|
+
boxShadow: "0 2px 5px rgba(0, 0, 0, 0.3)",
|
|
28
|
+
fontSize: "14px",
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<Typography
|
|
32
|
+
variant="body2"
|
|
33
|
+
style={{ marginBottom: "5px", fontWeight: "bold" }}
|
|
34
|
+
>
|
|
35
|
+
Year: {label}
|
|
36
|
+
</Typography>
|
|
37
|
+
<Typography variant="body2" style={{ marginBottom: "5px" }}>
|
|
38
|
+
Remaining Amount: {remainingAmount.toFixed(2)}
|
|
39
|
+
</Typography>
|
|
40
|
+
</Box>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const EmissionsReductionGraph = ({
|
|
47
|
+
initialEmissionAmount = 100,
|
|
48
|
+
desiredReductionPercentage = 0.5,
|
|
49
|
+
targetYear = 2030,
|
|
50
|
+
startYear = new Date().getFullYear(),
|
|
51
|
+
lineColor = null,
|
|
52
|
+
width = "100%",
|
|
53
|
+
height = 450,
|
|
54
|
+
carbonUnit = "lbs",
|
|
55
|
+
}) => {
|
|
56
|
+
const { palette } = useTheme();
|
|
57
|
+
|
|
58
|
+
const totalYears = targetYear - startYear;
|
|
59
|
+
|
|
60
|
+
const buildDecayLineArray = () => {
|
|
61
|
+
const decayRate = calculateEmissionsDecayRate(
|
|
62
|
+
desiredReductionPercentage,
|
|
63
|
+
totalYears
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return [...new Array(totalYears + 1)].map((_, idx) => ({
|
|
67
|
+
year: startYear + idx,
|
|
68
|
+
remainingAmount: initialEmissionAmount * Math.exp(decayRate * idx),
|
|
69
|
+
decayRate,
|
|
70
|
+
}));
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<ResponsiveContainer width={width} height={height}>
|
|
75
|
+
<LineChart
|
|
76
|
+
data={buildDecayLineArray()}
|
|
77
|
+
margin={{ top: 20, right: 30, left: 10, bottom: 10 }}
|
|
78
|
+
>
|
|
79
|
+
<CartesianGrid strokeDasharray="3 3" stroke="#bbb" />
|
|
80
|
+
<XAxis
|
|
81
|
+
dataKey="year"
|
|
82
|
+
stroke="#333"
|
|
83
|
+
tick={{ fill: "#333", fontSize: 12 }}
|
|
84
|
+
/>
|
|
85
|
+
<YAxis
|
|
86
|
+
tickFormatter={(value) => `${value} ${carbonUnit}`}
|
|
87
|
+
stroke="#333"
|
|
88
|
+
tick={{ fill: "#333", fontSize: 12 }}
|
|
89
|
+
/>
|
|
90
|
+
<Tooltip content={<CustomTooltip />} />
|
|
91
|
+
<Line
|
|
92
|
+
type="monotone"
|
|
93
|
+
dataKey="remainingAmount"
|
|
94
|
+
stroke={lineColor || palette.error.main}
|
|
95
|
+
strokeWidth={2}
|
|
96
|
+
dot={{
|
|
97
|
+
stroke: lineColor || palette.error.main,
|
|
98
|
+
strokeWidth: 2,
|
|
99
|
+
r: 6,
|
|
100
|
+
}}
|
|
101
|
+
activeDot={{ r: 8 }}
|
|
102
|
+
/>
|
|
103
|
+
</LineChart>
|
|
104
|
+
</ResponsiveContainer>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
export default EmissionsReductionGraph;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { Box, Grid, ButtonBase, Typography, Paper } from "@mui/material";
|
|
4
|
+
import { ThemeProvider } from "@mui/material/styles";
|
|
5
|
+
|
|
6
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
7
|
+
import {
|
|
8
|
+
faSteeringWheel,
|
|
9
|
+
faTrees,
|
|
10
|
+
faIcicles,
|
|
11
|
+
faHamburger,
|
|
12
|
+
faPiggyBank,
|
|
13
|
+
faMobile,
|
|
14
|
+
} from "@fortawesome/pro-solid-svg-icons";
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
kgsToTons,
|
|
18
|
+
hexToRgba,
|
|
19
|
+
tonsToLbs,
|
|
20
|
+
convertFootprintToDriving,
|
|
21
|
+
convertFootprintToIce,
|
|
22
|
+
footprintToHamburgers,
|
|
23
|
+
} from "@aclymatepackages/converters";
|
|
24
|
+
import { formatDecimal } from "@aclymatepackages/formatters";
|
|
25
|
+
import { useLayoutHelpers, mergeDarkTheme } from "@aclymatepackages/themes";
|
|
26
|
+
|
|
27
|
+
//source: Google Drive: Aclymate Team\Climate Accounting\Data\Tree Carbon Calculator\CarbonCalculator31.xls
|
|
28
|
+
const convertFootprintToTreeYears = (footprintTons) => {
|
|
29
|
+
const treeYearsDecimal = footprintTons / kgsToTons(160.6);
|
|
30
|
+
return formatDecimal(treeYearsDecimal.toFixed(1));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//source: https://shrinkthatfootprint.com/carbon-targets-for-your-footprint/
|
|
34
|
+
const footprintToCarbonBudgetPercent = (footprintTons) =>
|
|
35
|
+
`${formatDecimal((footprintTons / 4.1) * 100)}%`;
|
|
36
|
+
|
|
37
|
+
//SOURCE: https://news.energysage.com/how-many-watts-does-a-phone-charger-use/
|
|
38
|
+
//US average carbon intensity comes from carbon intensity data in app backend
|
|
39
|
+
const footprintToCellphoneYears = (footprintTons) => {
|
|
40
|
+
const US_AVG_TONS_CO2E_PER_KWH = 0.00043222913699413057;
|
|
41
|
+
const CELLPHONE_KWH_PER_YEAR = 1.83;
|
|
42
|
+
const footprintYears =
|
|
43
|
+
footprintTons / US_AVG_TONS_CO2E_PER_KWH / CELLPHONE_KWH_PER_YEAR;
|
|
44
|
+
|
|
45
|
+
return formatDecimal(footprintYears.toFixed(1));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const FootprintEquivalencies = ({
|
|
49
|
+
footprintTons,
|
|
50
|
+
exclusionCategories = [],
|
|
51
|
+
}) => {
|
|
52
|
+
const { theme, isMobile, isMedium } = useLayoutHelpers();
|
|
53
|
+
|
|
54
|
+
const [selectedCategoryIdx, setSelectedCategoryIdx] = useState(0);
|
|
55
|
+
|
|
56
|
+
const footprintEquivalentsCategories = [
|
|
57
|
+
{
|
|
58
|
+
type: "driving-emissions",
|
|
59
|
+
icon: faSteeringWheel,
|
|
60
|
+
buildString: (carbon, equivalency) =>
|
|
61
|
+
`Your ${carbon} lbs. of carbon is like driving a car ${equivalency} miles.`,
|
|
62
|
+
equivalency: convertFootprintToDriving(footprintTons),
|
|
63
|
+
color: "vehicles",
|
|
64
|
+
backgroundOpacity: 0.5,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "tree-sequestration",
|
|
68
|
+
icon: faTrees,
|
|
69
|
+
buildString: (carbon, equivalency) =>
|
|
70
|
+
`It would take an average oak tree ${equivalency} years to absorb your ${carbon} lbs. of carbon`,
|
|
71
|
+
equivalency: convertFootprintToTreeYears(footprintTons),
|
|
72
|
+
color: "secondary",
|
|
73
|
+
backgroundOpacity: 0.3,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: "melting-polar-bear",
|
|
77
|
+
icon: faIcicles,
|
|
78
|
+
buildString: (carbon, equivalency) =>
|
|
79
|
+
`Your ${carbon} lbs. of carbon is enough to permanently melt ${equivalency} square ${
|
|
80
|
+
equivalency === "1" ? "foot" : "feet"
|
|
81
|
+
} of Arctic sea ice`,
|
|
82
|
+
equivalency: formatDecimal(convertFootprintToIce(footprintTons)),
|
|
83
|
+
color: "travel",
|
|
84
|
+
backgroundOpacity: 0.3,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: "eating-hamburgers",
|
|
88
|
+
icon: faHamburger,
|
|
89
|
+
buildString: (carbon, equivalency) =>
|
|
90
|
+
`Your ${carbon} lbs. of carbon is equivalent to the emissions of eating ${equivalency} hamburgers`,
|
|
91
|
+
equivalency: formatDecimal(footprintToHamburgers(footprintTons)),
|
|
92
|
+
color: "mileage",
|
|
93
|
+
backgroundOpacity: 0.4,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: "carbon-budget",
|
|
97
|
+
icon: faPiggyBank,
|
|
98
|
+
buildString: (carbon, equivalency) =>
|
|
99
|
+
`Your ${carbon} lbs. of carbon is ${equivalency} of the annual carbon budget that we all need to achieve to reach our global climate goals.`,
|
|
100
|
+
equivalency: footprintToCarbonBudgetPercent(footprintTons),
|
|
101
|
+
color: "offices",
|
|
102
|
+
backgroundOpacity: 0.5,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: "cell-phone-charging",
|
|
106
|
+
icon: faMobile,
|
|
107
|
+
buildString: (carbon, equivalency) =>
|
|
108
|
+
`Your ${carbon} lbs. of carbon is enough to keep your cellphone charged for ${equivalency} years`,
|
|
109
|
+
equivalency: footprintToCellphoneYears(footprintTons),
|
|
110
|
+
color: "rides",
|
|
111
|
+
backgroundOpacity: 0.5,
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
const filteredEquivalentCategories = footprintEquivalentsCategories.filter(
|
|
116
|
+
({ type }) => !exclusionCategories.includes(type)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const { type, color, buildString, equivalency } =
|
|
120
|
+
filteredEquivalentCategories[selectedCategoryIdx];
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Grid container spacing={2} alignItems="stretch" justifyContent="center">
|
|
124
|
+
<Grid item lg={2} xs={12}>
|
|
125
|
+
<Grid
|
|
126
|
+
container
|
|
127
|
+
direction={isMedium ? "row" : "column"}
|
|
128
|
+
spacing={2}
|
|
129
|
+
justifyContent={isMedium ? "space-around" : "center"}
|
|
130
|
+
wrap="nowrap"
|
|
131
|
+
>
|
|
132
|
+
{filteredEquivalentCategories.map(({ icon, color }, idx) => (
|
|
133
|
+
<Grid item key={`grid-equivalency-carousel-icon-${idx}`}>
|
|
134
|
+
<ButtonBase onClick={() => setSelectedCategoryIdx(idx)}>
|
|
135
|
+
<Box
|
|
136
|
+
style={{
|
|
137
|
+
height: "50px",
|
|
138
|
+
width: "50px",
|
|
139
|
+
backgroundColor:
|
|
140
|
+
idx === selectedCategoryIdx
|
|
141
|
+
? theme.palette[color].main
|
|
142
|
+
: "white",
|
|
143
|
+
borderRadius: "50%",
|
|
144
|
+
}}
|
|
145
|
+
display="flex"
|
|
146
|
+
alignItems="center"
|
|
147
|
+
justifyContent="center"
|
|
148
|
+
>
|
|
149
|
+
<FontAwesomeIcon
|
|
150
|
+
icon={icon}
|
|
151
|
+
size="2x"
|
|
152
|
+
style={{
|
|
153
|
+
color:
|
|
154
|
+
idx === selectedCategoryIdx
|
|
155
|
+
? "white"
|
|
156
|
+
: theme.palette[color].main,
|
|
157
|
+
}}
|
|
158
|
+
/>
|
|
159
|
+
</Box>
|
|
160
|
+
</ButtonBase>
|
|
161
|
+
</Grid>
|
|
162
|
+
))}
|
|
163
|
+
</Grid>
|
|
164
|
+
</Grid>
|
|
165
|
+
<Grid item lg={6} xs={12}>
|
|
166
|
+
<Box display="flex" justifyContent="center">
|
|
167
|
+
<Box position="relative">
|
|
168
|
+
<img
|
|
169
|
+
alt={`${type}-image`}
|
|
170
|
+
src={`https://dashboard.aclymate.com/images/footprint-equivalencies/${type}.svg`}
|
|
171
|
+
style={{ width: "100%" }}
|
|
172
|
+
/>
|
|
173
|
+
<Paper
|
|
174
|
+
style={{
|
|
175
|
+
backgroundColor: hexToRgba(theme.palette[color].main, 0.85),
|
|
176
|
+
position: "absolute",
|
|
177
|
+
bottom: 0,
|
|
178
|
+
left: 0,
|
|
179
|
+
right: 0,
|
|
180
|
+
}}
|
|
181
|
+
>
|
|
182
|
+
<Box p={isMobile ? 0.25 : 1}>
|
|
183
|
+
<ThemeProvider theme={mergeDarkTheme}>
|
|
184
|
+
<Typography
|
|
185
|
+
variant={isMobile ? "subtitle2" : "subtitle1"}
|
|
186
|
+
align="center"
|
|
187
|
+
color="textPrimary"
|
|
188
|
+
>
|
|
189
|
+
{buildString(
|
|
190
|
+
formatDecimal(tonsToLbs(footprintTons)),
|
|
191
|
+
equivalency
|
|
192
|
+
)}
|
|
193
|
+
</Typography>
|
|
194
|
+
</ThemeProvider>
|
|
195
|
+
</Box>
|
|
196
|
+
</Paper>
|
|
197
|
+
</Box>
|
|
198
|
+
</Box>
|
|
199
|
+
</Grid>
|
|
200
|
+
</Grid>
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
export default FootprintEquivalencies;
|