Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes bugs with Planetcash selector #460

Merged
merged 5 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ const scheme =
: "https";

let APPUrl;
if (process.env.NEXT_PUBLIC_VERCEL_ENV === "preview") {
if (
process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" &&
process.env.DISABLE_VERCEL_REDIRECT !== "true"
) {
APPUrl = `${scheme}://${process.env.VERCEL_URL}`;
} else {
APPUrl = process.env.APP_URL;
Expand Down
1 change: 1 addition & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
"billingAddress": "Contact Details",
"treesInCountry": "{{treeCount}} trees, Plant-for-the-Planet",
"fundingPaymentLabel": "Donate {{amount}}, Plant-for-the-Planet",
"pcashPaymentLabel": "Load {{amount}} PlanetCash, Plant-for-the-Planet",
"bouquetPaymentLabel": "Donate {{amount}}, Plant-for-the-Planet",
"errorOccurred": "Something went wrong. Please feel free to take a screenshot and email us at [email protected].",
"dedicatedTo": "Dedicated to",
Expand Down
4 changes: 2 additions & 2 deletions src/Common/Types/QueryParamContextInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ export default interface QueryParamContextInterface {
paymentSetupCountry: string;
shouldSetPaymentDetails?: boolean;
}) => Promise<void>;
isPlanetCashActive: boolean;
setIsPlanetCashActive: Dispatch<SetStateAction<boolean>>;
isPlanetCashActive: boolean | null;
setIsPlanetCashActive: Dispatch<SetStateAction<boolean | null>>;
onBehalf: boolean;
setOnBehalf: Dispatch<SetStateAction<boolean>>;
onBehalfDonor: OnBehalfDonor;
Expand Down
20 changes: 20 additions & 0 deletions src/Donations/Components/DonationsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function DonationsForm(): ReactElement {
utmMedium,
utmSource,
isPackageWanted,
setPaymentRequest,
} = React.useContext(QueryParamContext);
const { t, i18n } = useTranslation(["common", "country", "donate"]);

Expand All @@ -78,6 +79,16 @@ function DonationsForm(): ReactElement {
React.useState(false);
const router = useRouter();

React.useEffect(() => {
setPaymentRequest(null);
}, []);

React.useEffect(() => {
if (isPlanetCashActive) {
setPaymentRequest(null);
}
}, [isPlanetCashActive]);

React.useEffect(() => {
setMinAmt(getMinimumAmountForCurrency(currency));
}, [currency]);
Expand Down Expand Up @@ -241,6 +252,15 @@ function DonationsForm(): ReactElement {
),
});
break;
case "planet-cash":
paymentLabel = t("pcashPaymentLabel", {
amount: getFormatedCurrency(
i18n.language,
currency,
paymentSetup.unitCost * quantity
),
});
break;
case "bouquet":
case "conservation":
paymentLabel = t("bouquetPaymentLabel", {
Expand Down
10 changes: 6 additions & 4 deletions src/Donations/Components/PaymentsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function PaymentsForm(): ReactElement {
utmMedium,
utmSource,
isPackageWanted,
setPaymentRequest,
} = React.useContext(QueryParamContext);

const [stripePromise, setStripePromise] =
Expand All @@ -100,6 +101,7 @@ function PaymentsForm(): ReactElement {

React.useEffect(() => {
setPaymentType("CARD");
setPaymentRequest(null);
}, []);

const sofortCountries = ["AT", "BE", "DE", "IT", "NL", "ES"];
Expand All @@ -111,7 +113,7 @@ function PaymentsForm(): ReactElement {
| string
| PaymentMethod
| PaypalApproveData
| PaypalErrorData,
| PaypalErrorData
) => {
if (!paymentSetup || !donationID) {
console.log("Missing payment options"); //TODOO - better error handling
Expand Down Expand Up @@ -144,7 +146,7 @@ function PaymentsForm(): ReactElement {
// Seems to work only for native pay. Should this be removed?
const onPaymentFunction = async (
paymentMethod: PaymentMethod,
paymentRequest: PaymentRequest,
paymentRequest: PaymentRequest
) => {
setPaymentType(paymentRequest._activeBackingLibraryName); //TODOO --_activeBackingLibraryName is a private variable?
const gateway = "stripe";
Expand Down Expand Up @@ -289,7 +291,7 @@ function PaymentsForm(): ReactElement {
query: { ...router.query, step: CONTACT },
},
undefined,
{ shallow: true },
{ shallow: true }
);
}}
className="d-flex"
Expand Down Expand Up @@ -420,7 +422,7 @@ function PaymentsForm(): ReactElement {
totalCost={getFormatedCurrency(
i18n.language,
currency,
paymentSetup?.unitCost * quantity,
paymentSetup?.unitCost * quantity
)}
onPaymentFunction={(providerObject: PaymentMethod) =>
onSubmitPayment("stripe", "card", providerObject)
Expand Down
43 changes: 26 additions & 17 deletions src/Donations/Micros/PlanetCashSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const PlanetCashSelector: FC = () => {
country,
setcountry,
frequency,
paymentRequest,
} = useContext(QueryParamContext);
const router = useRouter();

Expand All @@ -37,20 +36,28 @@ const PlanetCashSelector: FC = () => {
}, [paymentSetup?.unitCost, quantity, setIsPlanetCashActive]);

useEffect(() => {
// On Load If selected country is planetCash Country and balance is sufficient activate planetCash.

if (
country === profile?.planetCash?.country &&
paymentSetup &&
paymentSetup.unitCost * quantity <=
profile.planetCash.balance / 100 + profile.planetCash.creditLimit / 100
) {
setIsPlanetCashActive(true);
}
if (frequency !== "once") {
if (frequency !== "once" && isPlanetCashActive !== null) {
setIsPlanetCashActive(false);
} else {
if (
isPlanetCashActive === null &&
country === profile?.planetCash?.country &&
paymentSetup &&
paymentSetup.unitCost * quantity <=
(profile.planetCash.balance + profile.planetCash.creditLimit) / 100
) {
setIsPlanetCashActive(true);
}
}
}, [paymentRequest, frequency]);
}, [
country,
profile,
paymentSetup,
quantity,
frequency,
isPlanetCashActive,
frequency,
]);

useEffect(() => {
// This is done to lock the transaction with PlanetCash in a single currency.
Expand Down Expand Up @@ -208,11 +215,13 @@ const PlanetCashSelector: FC = () => {
</div>
<div title={disabledReason() ? disabledReason() : ""}>
<ToggleSwitch
checked={isPlanetCashActive}
checked={isPlanetCashActive === true}
disabled={shouldPlanetCashDisable()}
onChange={() =>
setIsPlanetCashActive((isPlanetCashActive) => !isPlanetCashActive)
}
onChange={() => {
setIsPlanetCashActive(
(isPlanetCashActive) => !isPlanetCashActive
);
}}
/>
</div>
</div>
Expand Down
9 changes: 9 additions & 0 deletions src/Donations/PaymentMethods/PaymentMethodTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ export default function PaymentMethodTabs({
),
});
break;
case "planet-cash":
paymentLabel = t("pcashPaymentLabel", {
amount: getFormatedCurrency(
i18n.language,
currency,
paymentSetup.unitCost * quantity
),
});
break;
case "bouquet":
case "conservation":
paymentLabel = t("bouquetPaymentLabel", {
Expand Down
42 changes: 30 additions & 12 deletions src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
} from "@stripe/stripe-js/types/stripe-js/payment-request";
import { PaymentMethod } from "@stripe/stripe-js/types/api/payment-methods";
import { Stripe } from "@stripe/stripe-js/types/stripe-js/stripe";
import Skeleton from "@mui/material/Skeleton";

interface PaymentButtonProps {
country: string;
Expand All @@ -31,30 +32,28 @@
paymentSetup: PaymentOptions;
}

export const PaymentRequestCustomButton = ({
country,
currency,
amount,
onPaymentFunction,
continueNext,
isPaymentPage,
paymentLabel,
frequency,
paymentSetup,
}: PaymentButtonProps): ReactElement | null => {
const isApplePayEnabled = process.env.ENABLE_APPLE_PAY === "true" || false;
const isGooglePayEnabled = process.env.ENABLE_GOOGLE_PAY === "true" || false;
const { t, ready } = useTranslation(["common"]);
const { paymentRequest, setPaymentRequest } = useContext(QueryParamContext);

const stripe = useStripe();
const [canMakePayment, setCanMakePayment] = useState(false);
const [paymentLoading, setPaymentLoading] = useState(false);

useEffect(() => {
setPaymentRequest(null);
}, []);
// Tracks if native pay buttons were shown at least once to prevent layout jerks
const [wasNativePayInit, setWasNativePayInit] = useState(false);

Check notice on line 56 in src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx

View check run for this annotation

codefactor.io / CodeFactor

src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx#L35-L56

Complex Method
useEffect(() => {
if (
stripe &&
Expand All @@ -75,17 +74,16 @@
pr.canMakePayment().then((result) => {
if (result) {
setPaymentRequest(pr);
setWasNativePayInit(true);
}
});
}
}, [stripe, paymentRequest, country, currency, amount]);

useEffect(() => {
if (stripe && paymentRequest) {
setPaymentRequest(null);
setCanMakePayment(false);
setPaymentLoading(false);
}
setPaymentRequest(null);
setCanMakePayment(false);
setPaymentLoading(false);
}, [country, currency, amount]);

useEffect(() => {
Expand Down Expand Up @@ -121,7 +119,10 @@
);
}
return () => {
if (paymentRequest && !paymentLoading) {
if (
paymentRequest &&
paymentRequest.hasRegisteredListener("paymentmethod")
) {
paymentRequest.off("paymentmethod", () => {
setPaymentLoading(false);
});
Expand Down Expand Up @@ -194,8 +195,25 @@
<div className="separator-text mb-10">{t("or")}</div>
)}
</div>
) : null
) : null}
) : (
<></>
)
) : wasNativePayInit ? (
//Loader shown if native pay was initiated at least once to avoid a jerky effect when payment details change
<div className="w-100">
<Skeleton
className="mb-10"
variant="rectangular"
width={"100%"}
height={40}
/>
{!isPaymentPage && (
<div className="separator-text mb-10">{t("or")}</div>
)}
</div>
) : (
<></>
)}

{!isPaymentPage && (
<button
Expand Down
22 changes: 13 additions & 9 deletions src/Layout/QueryParamContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@
const [transferDetails, setTransferDetails] =
useState<BankTransferDetails | null>(null);

const [isPlanetCashActive, setIsPlanetCashActive] = useState(false);
const [isPlanetCashActive, setIsPlanetCashActive] = useState<boolean | null>(
null
);

// Only used when planetCash is active
const [onBehalf, setOnBehalf] = useState(false);
Expand All @@ -151,7 +153,7 @@

const [donation, setDonation] = useState<Donation | null>(null);
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
null,
null
);

const [errors, setErrors] = React.useState<SerializedError[] | null>(null);
Expand All @@ -163,8 +165,9 @@
setshowErrorCard,
shouldQueryParamAdd: false,
};
const response: { data: Record<string, string> } =
await apiRequest(requestParams);
const response: { data: Record<string, string> } = await apiRequest(
requestParams
);
setEnabledCurrencies(response.data);
} catch (err) {
console.log(err);
Expand Down Expand Up @@ -198,7 +201,7 @@

function testURL(url: string) {
const pattern = new RegExp(
/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g,
/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g
);
// regex source https://tutorial.eyehunts.com/js/url-regex-validation-javascript-example-code/
return !!pattern.test(url);
Expand Down Expand Up @@ -242,7 +245,7 @@
const projects = response.data as Project[];
if (projects) {
const allowedDonationsProjects = projects.filter(
(project) => project.properties.allowDonations === true,
(project) => project.properties.allowDonations === true
);
setAllProjects(allowedDonationsProjects);
if (allowedDonationsProjects?.length < 6) {
Expand Down Expand Up @@ -293,55 +296,55 @@
}
}, [isLoading, isAuthenticated, loadProfile]);

useEffect(() => {
const regex = /^pcash_/;
if (router.query.to && regex.test(router.query.to as string)) {
router.push("/");
} else if (router.query.to?.toString().toLowerCase() === "planetcash") {
if (
!queryToken &&
!router.query.token &&
!isLoading &&
!isAuthenticated
) {
loginWithRedirect({
redirectUri: window?.location.href,
});
} else {
if (profile && profile?.planetCash?.account) {
loadPaymentSetup({
projectGUID: profile?.planetCash?.account,
paymentSetupCountry: country,
shouldSetPaymentDetails: true,
});
setdonationStep(1);
} else if (!profile?.planetCash) {
if (router.query.token) {
if (validateToken(router.query.token as string)) {
if (!profile) {
loadProfile();
} else if (!profile?.planetCash && profile?.displayName) {
showPlanetCashSignUpScreen();
}
} else {
// If token is invalid force user to login
router.push("/?to=planetcash&step=donate");
}
} else if (profile?.displayName) {
showPlanetCashSignUpScreen();
}
}
}
}
}, [
router.query.to,
country,
profile,
isLoading,
isAuthenticated,
router.query.token,
]);

Check notice on line 347 in src/Layout/QueryParamContext.tsx

View check run for this annotation

codefactor.io / CodeFactor

src/Layout/QueryParamContext.tsx#L299-L347

Complex Method
useEffect(() => {
const regex = /^pcash_/;
if (
Expand Down Expand Up @@ -373,7 +376,7 @@
const found = countriesData.some(
(arrayCountry) =>
arrayCountry.countryCode?.toUpperCase() ===
config.data.country?.toUpperCase(),
config.data.country?.toUpperCase()
);
if (found) {
// This is to make sure donations which are already created with some country do not get affected by country from user config
Expand Down Expand Up @@ -492,8 +495,9 @@
tenant,
locale: i18n.language,
};
const paymentSetupData: { data: PaymentOptions } =
await apiRequest(requestParams);
const paymentSetupData: { data: PaymentOptions } = await apiRequest(
requestParams
);
if (paymentSetupData.data) {
const paymentSetup = paymentSetupData.data;
if (shouldSetPaymentDetails) {
Expand Down
Loading