diff --git a/src/layout/ResultActions.jsx b/src/layout/ResultActions.jsx new file mode 100644 index 000000000..d1f946eef --- /dev/null +++ b/src/layout/ResultActions.jsx @@ -0,0 +1,88 @@ +// This component enables the user to download or share the results generated by +// PolicyEngine by showing the following sequence of buttons with appropriate +// icons: +// - Download the chart as a png file +// - Download the data as a csv file +// - Copy the link for the result +// - Share the result on Twitter +// - Share the result on Facebook +// - Share the result on LinkedIn + +import style from "../style"; + +import { Button, Tooltip } from "antd"; +import { + TwitterOutlined, + FacebookFilled, + LinkedinFilled, + LinkOutlined, + FileImageOutlined, + FileTextOutlined, +} from "@ant-design/icons"; +import React from "react"; + +export default function ResultActions(props) { + const { copyLink, twitterLink, facebookLink, linkedInLink } = props; + return ( +
+ {props.downloadPng && ( + +
+ ); +} diff --git a/src/layout/ResultsPanel.jsx b/src/layout/ResultsPanel.jsx index f74147653..1a405b85f 100644 --- a/src/layout/ResultsPanel.jsx +++ b/src/layout/ResultsPanel.jsx @@ -12,6 +12,7 @@ const ResultsPanel = forwardRef((props, ref) => { paddingLeft: mobile ? 5 : 20, paddingRight: mobile ? 5 : 20, height: "100%", + overflow: "auto", ...style, }} > diff --git a/src/pages/household/output/HouseholdOutput.jsx b/src/pages/household/output/HouseholdOutput.jsx index 54e35db54..85b30d592 100644 --- a/src/pages/household/output/HouseholdOutput.jsx +++ b/src/pages/household/output/HouseholdOutput.jsx @@ -9,15 +9,9 @@ import MarginalTaxRates from "./MarginalTaxRates"; import NetIncomeBreakdown from "./NetIncomeBreakdown"; import PoliciesModelledPopup from "./PoliciesModelledPopup"; import HOUSEHOLD_OUTPUT_TREE from "./tree"; -import { - TwitterOutlined, - FacebookFilled, - LinkedinFilled, - LinkOutlined, -} from "@ant-design/icons"; import React from "react"; import { message } from "antd"; -import style from "../../../style"; +import ResultActions from "layout/ResultActions"; export default function HouseholdOutput(props) { const [searchParams] = useSearchParams(); @@ -126,104 +120,31 @@ export default function HouseholdOutput(props) { ); } + function copyLink() { + navigator.clipboard.writeText(window.location.href); + message.info("Link copied to clipboard"); + } + const url = encodeURIComponent(window.location.href); - const link = ( - { - navigator.clipboard.writeText(window.location.href); - message.info("Link copied to clipboard"); - }} - > - - - ); const encodedPolicyLabel = encodeURIComponent(policyLabel); const urlParams = new URLSearchParams(window.location.search); const householdId = urlParams.get("household"); - let twitter; - if (reformLabel == "Current law") { - twitter = ( - - - - ); - } else { - twitter = ( - - - - ); - } + const twitterLink = + reformLabel == "Current law" + ? `https://twitter.com/intent/tweet?url=${url}&text=Household%20%23${householdId}%2C%20on%20PolicyEngine` + : `https://twitter.com/intent/tweet?url=${url}&text=Impacts%20of%20${encodedPolicyLabel}%20on%20Household%20%23${householdId}%2C%20on%20PolicyEngine`; + const facebookLink = `https://www.facebook.com/sharer/sharer.php?u=${url}`; + const linkedInLink = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`; - const facebook = ( - - - - ); - const linkedIn = ( - - - - ); - const commonStyle = { - border: "1px solid #ccc", - borderRadius: "0px", - padding: "6px", - marginRight: "-1px", - }; - const shareItems = [link, twitter, facebook, linkedIn]; - const shareDivs = shareItems.map((item, index) => ( -
- {item} -
- )); - - pane = ( - <> -
-
- Share this result -
-
- {shareDivs} -
-
+ return ( + {pane} + - + ); - - return {pane}; } diff --git a/src/pages/policy/output/PolicyOutput.jsx b/src/pages/policy/output/PolicyOutput.jsx index ee670dc20..d2a319477 100644 --- a/src/pages/policy/output/PolicyOutput.jsx +++ b/src/pages/policy/output/PolicyOutput.jsx @@ -24,19 +24,9 @@ import AverageImpactByWealthDecile from "./AverageImpactByWealthDecile"; import RelativeImpactByWealthDecile from "./RelativeImpactByWealthDecile"; import IntraWealthDecileImpact from "./IntraWealthDecileImpact"; import DeepPovertyImpactByGender from "./DeepPovertyImpactByGender"; -import { Result, Steps, Progress, Button, Tooltip } from "antd"; -import { - TwitterOutlined, - FacebookFilled, - LinkedinFilled, - LinkOutlined, - FileImageOutlined, - CheckCircleFilled, - CloseCircleFilled, - FileTextOutlined, -} from "@ant-design/icons"; +import { Result, Steps, Progress, message } from "antd"; +import { CheckCircleFilled, CloseCircleFilled } from "@ant-design/icons"; import React from "react"; -import { message } from "antd"; import Analysis from "./Analysis"; import style from "../../../style"; import { PovertyChangeProvider } from "./PovertyChangeContext"; @@ -44,6 +34,7 @@ import html2canvas from "html2canvas"; import { saveAs } from "file-saver"; import { useScreenshot } from "use-react-screenshot"; +import ResultActions from "layout/ResultActions"; export function RegionSelector(props) { const { metadata } = props; @@ -520,10 +511,28 @@ export default function PolicyOutput(props) { ); } - const url = encodeURIComponent(window.location.href); - const encodedPolicyLabel = encodeURIComponent(policyLabel); + async function downloadPng() { + const downloadableContent = document.getElementById("downloadable-content"); + if (downloadableContent) { + const paddedDiv = document.createElement("div"); + paddedDiv.style.padding = "20px"; + paddedDiv.style.backgroundColor = "white"; + paddedDiv.style.display = "inline-block"; + paddedDiv.style.boxSizing = "content-box"; // Add this line + paddedDiv.appendChild(downloadableContent.cloneNode(true)); - const downloadCSV = () => { + document.body.appendChild(paddedDiv); + + const canvas = await html2canvas(paddedDiv); + + document.body.removeChild(paddedDiv); + canvas.toBlob((blob) => { + saveAs(blob, filename + ".png"); + }); + } + } + + function downloadCsv() { const data = childRef.current.getCsvData(); if (data !== null) { const csvContent = data @@ -542,28 +551,18 @@ export default function PolicyOutput(props) { URL.revokeObjectURL(url); } - }; - - const downloadImage = async () => { - const downloadableContent = document.getElementById("downloadable-content"); - if (downloadableContent) { - const paddedDiv = document.createElement("div"); - paddedDiv.style.padding = "20px"; - paddedDiv.style.backgroundColor = "white"; - paddedDiv.style.display = "inline-block"; - paddedDiv.style.boxSizing = "content-box"; // Add this line - paddedDiv.appendChild(downloadableContent.cloneNode(true)); - - document.body.appendChild(paddedDiv); + } - const canvas = await html2canvas(paddedDiv); + function copyLink() { + navigator.clipboard.writeText(window.location.href); + message.info("Link copied to clipboard"); + } - document.body.removeChild(paddedDiv); - canvas.toBlob((blob) => { - saveAs(blob, filename + ".png"); - }); - } - }; + const url = encodeURIComponent(window.location.href); + const encodedPolicyLabel = encodeURIComponent(policyLabel); + const twitterLink = `https://twitter.com/intent/tweet?url=${url}&text=${encodedPolicyLabel}%2C%20on%20PolicyEngine`; + const facebookLink = `https://www.facebook.com/sharer/sharer.php?u=${url}`; + const linkedInLink = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`; const embed = new URLSearchParams(window.location.search).get("embed"); const bottomElements = @@ -631,79 +630,22 @@ export default function PolicyOutput(props) { setHasShownPopulationImpactPopup={setHasShownPopulationImpactPopup} /> {pane} -
- {!preparingForScreenshot && ( - <> - {showFileDownloadButtons && ( - -
{!preparingForScreenshot && ( - + <> + + + )} );