From a4cdea439c74d78072f2f4005b02b405decdae4f Mon Sep 17 00:00:00 2001 From: Harsh Vitra Date: Thu, 22 Jul 2021 17:42:35 +0530 Subject: [PATCH] Proof of concept for recurrency --- iframetest.html | 2 +- next.config.js | 1 + src/Common/Types/index.tsx | 1 + src/Donations/Components/DonationsForm.tsx | 13 ++ src/Donations/Components/PaymentsForm.tsx | 49 ++++++-- src/Donations/Micros/FrequencyOptions.tsx | 36 ++++++ .../PaymentMethods/PaymentFunctions.ts | 4 + .../PaymentMethods/PaymentMethodTabs.tsx | 3 +- .../PaymentRequestCustomButton.tsx | 30 ++++- src/Layout/QueryParamContext.tsx | 9 +- styles/donations.scss | 119 +++++++++--------- 11 files changed, 188 insertions(+), 79 deletions(-) create mode 100644 src/Donations/Micros/FrequencyOptions.tsx diff --git a/iframetest.html b/iframetest.html index ba672863..3a2c8223 100644 --- a/iframetest.html +++ b/iframetest.html @@ -5,4 +5,4 @@ }

This is a different landing page

- \ No newline at end of file + \ No newline at end of file diff --git a/next.config.js b/next.config.js index a7f3af6b..91961181 100644 --- a/next.config.js +++ b/next.config.js @@ -120,6 +120,7 @@ module.exports = withPlugins([[withBundleAnalyzer], [withSourceMaps]], { VERCEL_URL: process.env.VERCEL_URL, ESRI_CLIENT_ID: process.env.ESRI_CLIENT_ID, ESRI_CLIENT_SECRET: process.env.ESRI_CLIENT_SECRET, + RECURRENCY: process.env.RECURRENCY, }, trailingSlash: false, reactStrictMode: true, diff --git a/src/Common/Types/index.tsx b/src/Common/Types/index.tsx index c3f67bc7..4c6918ca 100644 --- a/src/Common/Types/index.tsx +++ b/src/Common/Types/index.tsx @@ -98,4 +98,5 @@ export interface CreateDonationFunctionProps { setdonationID: any; token: any; setshowErrorCard: Function; + frequency: string | null; } \ No newline at end of file diff --git a/src/Donations/Components/DonationsForm.tsx b/src/Donations/Components/DonationsForm.tsx index db38c593..f7af71fa 100644 --- a/src/Donations/Components/DonationsForm.tsx +++ b/src/Donations/Components/DonationsForm.tsx @@ -19,6 +19,7 @@ import { useAuth0 } from "@auth0/auth0-react"; import DonationAmount from "../Micros/DonationAmount"; import TreeDonation from "../Micros/DonationTypes/TreeDonation"; import FundingDonations from "../Micros/DonationTypes/FundingDonations"; +import FrequencyOptions from "../Micros/FrequencyOptions"; function DonationsForm() { const { @@ -37,6 +38,7 @@ function DonationsForm() { isTaxDeductible, setshowErrorCard, queryToken, + frequency } = React.useContext(QueryParamContext); const { t, i18n } = useTranslation(["common", "country", "donate"]); @@ -91,6 +93,7 @@ function DonationsForm() { setdonationID, token, setshowErrorCard, + frequency }).then(async (res) => { let token = null; if ((!isLoading && isAuthenticated) || queryToken) { @@ -130,6 +133,15 @@ function DonationsForm() { <> )} + {process.env.RECURRENCY && projectDetails.purpose === "trees" ? ( +
+ +
+ ) : ( + <> + )} + + {projectDetails.purpose === "funds" ? ( ) : ( @@ -169,6 +181,7 @@ function DonationsForm() { `country:${projectDetails.country.toLowerCase()}` ), })} + frequency={frequency} /> ) : (
diff --git a/src/Donations/Components/PaymentsForm.tsx b/src/Donations/Components/PaymentsForm.tsx index 4d3e7397..fbb0401e 100644 --- a/src/Donations/Components/PaymentsForm.tsx +++ b/src/Donations/Components/PaymentsForm.tsx @@ -60,6 +60,7 @@ function PaymentsForm({}: Props): ReactElement { setshowErrorCard, hideTaxDeduction, queryToken, + frequency, } = React.useContext(QueryParamContext); React.useEffect(() => { @@ -116,6 +117,7 @@ function PaymentsForm({}: Props): ReactElement { setdonationID, token, setshowErrorCard, + frequency, }); if (donation) { @@ -233,34 +235,65 @@ function PaymentsForm({}: Props): ReactElement { diff --git a/src/Donations/Micros/FrequencyOptions.tsx b/src/Donations/Micros/FrequencyOptions.tsx new file mode 100644 index 00000000..ddb3b918 --- /dev/null +++ b/src/Donations/Micros/FrequencyOptions.tsx @@ -0,0 +1,36 @@ +import React, { ReactElement } from "react"; +import { QueryParamContext } from "../../Layout/QueryParamContext"; + +interface Props {} + +function FrequencyOptions({}: Props): ReactElement { + const { paymentSetup, setfrequency,frequency } = React.useContext(QueryParamContext); + console.log("paymentSetup", paymentSetup); + + return ( +
+ {paymentSetup.frequencies && paymentSetup.frequencies.length > 0 ? ( + paymentSetup.frequencies.map((frequencyOption:any, index:any) => { + return ( +
setfrequency(frequencyOption) + } + > + {frequencyOption} +
+ ); + }) + ) : ( + <> + )} +
+ ); +} + +export default FrequencyOptions; diff --git a/src/Donations/PaymentMethods/PaymentFunctions.ts b/src/Donations/PaymentMethods/PaymentFunctions.ts index e8a93599..1833157b 100644 --- a/src/Donations/PaymentMethods/PaymentFunctions.ts +++ b/src/Donations/PaymentMethods/PaymentFunctions.ts @@ -91,6 +91,7 @@ export async function createDonationFunction({ setdonationID, token, setshowErrorCard, + frequency }: CreateDonationFunctionProps) { const taxDeductionCountry = isTaxDeductible ? country : null; const donationData = createDonationData({ @@ -102,6 +103,7 @@ export async function createDonationFunction({ taxDeductionCountry, isGift, giftDetails, + frequency }); try { let donation; @@ -153,6 +155,7 @@ export function createDonationData({ taxDeductionCountry, isGift, giftDetails, + frequency }: any) { let donationData = { purpose: projectDetails.purpose, @@ -161,6 +164,7 @@ export function createDonationData({ amount: Math.round((unitCost * quantity + Number.EPSILON) * 100) / 100, currency, donor: { ...contactDetails }, + frequency:frequency === 'once' ? null : frequency }; if (taxDeductionCountry) { donationData = { diff --git a/src/Donations/PaymentMethods/PaymentMethodTabs.tsx b/src/Donations/PaymentMethods/PaymentMethodTabs.tsx index b06068f5..90016746 100644 --- a/src/Donations/PaymentMethods/PaymentMethodTabs.tsx +++ b/src/Donations/PaymentMethods/PaymentMethodTabs.tsx @@ -61,7 +61,7 @@ export default function PaymentMethodTabs({ ); } - const { country, currency, projectDetails, paymentSetup, quantity } = + const { country, currency, projectDetails, paymentSetup, quantity,frequency } = React.useContext(QueryParamContext); return ( @@ -149,6 +149,7 @@ export default function PaymentMethodTabs({ country: t(`country:${projectDetails.country.toLowerCase()}`), }) } + frequency={frequency} /> )}
diff --git a/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx b/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx index 822e501a..38ee2afe 100644 --- a/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx +++ b/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx @@ -16,7 +16,8 @@ interface PaymentButtonProps { onPaymentFunction: Function; continueNext: Function; isPaymentPage: boolean; - paymentLabel:string; + paymentLabel: string; + frequency: string | null; } export const PaymentRequestCustomButton = ({ country, @@ -25,7 +26,8 @@ export const PaymentRequestCustomButton = ({ onPaymentFunction, continueNext, isPaymentPage, - paymentLabel + paymentLabel, + frequency, }: PaymentButtonProps) => { const { t, ready } = useTranslation(["common"]); @@ -111,7 +113,10 @@ export const PaymentRequestCustomButton = ({ {stripeAllowedCountries.includes(country) && canMakePayment && paymentRequest && - paymentRequest._canMakePaymentAvailability ? ( + paymentRequest._canMakePaymentAvailability && + (frequency !== "once" + ? paymentSetup?.gateways.stripe.recurrency.enabled.includes("stripe_cc") + : true) ? ( paymentRequest._canMakePaymentAvailability.APPLE_PAY ? (
{!isPaymentPage && (
{t("or")}
@@ -141,7 +152,11 @@ export const PaymentRequestCustomButton = ({ > {isPaymentPage ? "" : t("donateWith")}{" "} {!isPaymentPage && ( @@ -184,6 +199,7 @@ interface NativePayProps { continueNext: Function; isPaymentPage: boolean; paymentLabel: string; + frequency: string | null; } export const NativePay = ({ country, @@ -193,7 +209,8 @@ export const NativePay = ({ paymentSetup, continueNext, isPaymentPage, - paymentLabel + paymentLabel, + frequency, }: NativePayProps) => { const [stripePromise, setStripePromise] = useState(() => getStripe(paymentSetup) @@ -228,6 +245,7 @@ export const NativePay = ({ continueNext={continueNext} isPaymentPage={isPaymentPage} paymentLabel={paymentLabel} + frequency={frequency} /> ); diff --git a/src/Layout/QueryParamContext.tsx b/src/Layout/QueryParamContext.tsx index dd9ba497..4065603b 100644 --- a/src/Layout/QueryParamContext.tsx +++ b/src/Layout/QueryParamContext.tsx @@ -54,7 +54,9 @@ export const QueryParamContext = React.createContext({ queryToken:"", setqueryToken: (value: string) => "", sethideTaxDeduction: (value: boolean) => {}, - setisDirectDonation:(value: boolean) => {} + setisDirectDonation:(value: boolean) => {}, + frequency: "", + setfrequency: (value: string) => {}, }); export default function QueryParamProvider({ children }: any) { @@ -94,6 +96,7 @@ export default function QueryParamProvider({ children }: any) { const [quantity, setquantity] = useState(50); + const [frequency, setfrequency] = useState("once"); const [isGift, setisGift] = useState(false); const [giftDetails, setgiftDetails] = useState({ @@ -376,7 +379,9 @@ export default function QueryParamProvider({ children }: any) { setpaymentSetup, sethideTaxDeduction, setallowTaxDeductionChange, - setisDirectDonation + setisDirectDonation, + frequency, + setfrequency }} > {children} diff --git a/styles/donations.scss b/styles/donations.scss index 7ec6a7f1..750ebae6 100644 --- a/styles/donations.scss +++ b/styles/donations.scss @@ -205,57 +205,56 @@ flex-direction: row; flex-wrap: wrap; justify-content: space-between; - .tree-selection-option { - width: 90px; // Width 100px supported from - height: 54px; - border: 1px solid $greyColor; - border-radius: 4px; - display: flex; - padding: 8px; - justify-content: center; - align-items: center; - &.tree-selection-option-selected, - &:hover, - &:focus { - cursor: pointer; - border: 1px solid $primaryColor; - > svg { - filter: grayscale(0%) opacity(1); - } - .tree-selection-option-text { - color: $primaryFontColor; - p{ - color: $primaryFontColor; - } - } - } - &:hover { - transform: scale(1.05); - } - &:active { - transform: scale(0.98); - } +} +.tree-selection-option { + width: 90px; // Width 100px supported from + height: 54px; + border: 1px solid $greyColor; + border-radius: 4px; + display: flex; + padding: 8px; + justify-content: center; + align-items: center; + &.tree-selection-option-selected, + &:hover, + &:focus { + cursor: pointer; + border: 1px solid $primaryColor; > svg { - filter: grayscale(100%) opacity(0.5); + filter: grayscale(0%) opacity(1); } .tree-selection-option-text { - text-align: center; - line-height: 1; - margin-left: 10px; - color: $darkGreyColor; - > p { - font-size: 14px; - font-weight: 800; - color: $darkGreyColor; - } - > span { - font-size: 12px; + color: $primaryFontColor; + p { + color: $primaryFontColor; } } } + &:hover { + transform: scale(1.05); + } + &:active { + transform: scale(0.98); + } + > svg { + filter: grayscale(100%) opacity(0.5); + } + .tree-selection-option-text { + text-align: center; + line-height: 1; + margin-left: 10px; + color: $darkGreyColor; + > p { + font-size: 14px; + font-weight: 800; + color: $darkGreyColor; + } + > span { + font-size: 12px; + } + } } - .funding-selection-options-container { display: flex; flex-direction: row; @@ -318,7 +317,6 @@ } } - .custom-selection { flex-grow: 1; margin-left: 25px; @@ -335,11 +333,11 @@ .suggestion { min-width: 100%; &:nth-child(even) { - background-color: rgba(var(--background-color-dark),0.6); + background-color: rgba(var(--background-color-dark), 0.6); } padding: 12px; border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1); - &:hover{ + &:hover { cursor: pointer; background-color: $backgroundColorDark; } @@ -360,7 +358,8 @@ } } -.custom-tree-input, .funding-custom-tree-input { +.custom-tree-input, +.funding-custom-tree-input { border: 0px; border-bottom: 1px solid $primaryFontColor; margin: 0px 10px; @@ -375,7 +374,7 @@ font-size: 16px; letter-spacing: 0.5px; } -.funding-custom-tree-input{ +.funding-custom-tree-input { text-align: center; margin: 0px; margin-left: -16px; @@ -419,16 +418,16 @@ &:hover { cursor: pointer; color: $primaryFontColor; - background-color: #F2F2F7; - border: 0.5px solid #F2F2F7; + background-color: #f2f2f7; + border: 0.5px solid #f2f2f7; } .check-mark { display: none; } } .payment-method-selected { - background-color: #F2F2F7; - border: 0.5px solid #F2F2F7; + background-color: #f2f2f7; + border: 0.5px solid #f2f2f7; color: $primaryFontColor; font-weight: 600; @@ -581,8 +580,8 @@ } .contact-details-info { - p{ - color: white!important; + p { + color: white !important; } button { display: flex; @@ -614,11 +613,9 @@ max-width: 420px; padding: 30px; } - .tree-selection-options-container { - .tree-selection-option { - width: 100px; - padding: 12px; - } + .tree-selection-option { + width: 100px; + padding: 12px; } .funding-selection-options-container { .funding-selection-option { @@ -773,6 +770,6 @@ } } -.ElementsApp .Icon-fill{ +.ElementsApp .Icon-fill { fill: $primaryFontColor; -} \ No newline at end of file +}