Files
freeCodeCamp/client/src/components/Donation/walletsButton.tsx
Ahmad Abdolsaheb b623c340a9 feat(client): add google pay (#43117)
* feat: initial button setup client

* feat: rename walletsButton to .tsx

* chore: typescriptize wallet component

* chore: re-add keys to config, env, etc + check in gatsby-node

* feat: refactor donate form and wallet component

* feat(client): set labels correctly

* chore: add stripe package back to server

* chore: add stripe back to allowed paths

* chore: copy donate.js code from PR #41924

* feat: attempt to make back end work

* feat: make redux work

* feat: clean up

* feat: hokify

* feat: add error handling

* fix: back-end should be working

* fix: type errors

* fix: clean up back-end

* feat:addd styles

* feat: connect the client to the api

* feat: display wallets button everywhere

* test: add stripe key for cypress action

* test: fix for cypress tests

* test: cypress tests again

* test: maybe?

* test: more

* test: more

* test: more

* test

* askdfjasklfj

* fix: tests finally?

* revert: remove space from cypress yaml action

* remove logs

Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
2021-08-08 23:22:25 +03:00

132 lines
3.2 KiB
TypeScript

import {
PaymentRequestButtonElement,
Elements,
ElementsConsumer
} from '@stripe/react-stripe-js';
import { Stripe, loadStripe } from '@stripe/stripe-js';
import type { Token, PaymentRequest } from '@stripe/stripe-js';
import React, { useState, useEffect } from 'react';
import envData from '../../../../config/env.json';
import { AddDonationData } from './PaypalButton';
const { stripePublicKey }: { stripePublicKey: string | null } = envData;
interface WrapperProps {
label: string;
amount: number;
theme: string;
postStripeDonation: (
token: Token,
payerEmail: string | undefined,
payerName: string | undefined
) => void;
onDonationStateChange: (donationState: AddDonationData) => void;
refreshErrorMessage: string;
}
interface WalletsButtonProps extends WrapperProps {
stripe: Stripe | null;
}
const WalletsButton = ({
stripe,
label,
amount,
theme,
refreshErrorMessage,
postStripeDonation,
onDonationStateChange
}: WalletsButtonProps) => {
const [token, setToken] = useState<Token | null>(null);
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
null
);
const [canMakePayment, checkpaymentPossiblity] = useState(false);
useEffect(() => {
if (!stripe) {
return;
}
const pr = stripe.paymentRequest({
country: 'US',
currency: 'usd',
total: { label, amount },
requestPayerName: true,
requestPayerEmail: true,
disableWallets: ['browserCard']
});
pr.on('token', event => {
const { token, payerEmail, payerName } = event;
setToken(token);
event.complete('success');
postStripeDonation(token, payerEmail, payerName);
});
void pr.canMakePayment().then(canMakePaymentRes => {
if (canMakePaymentRes) {
setPaymentRequest(pr);
checkpaymentPossiblity(true);
} else {
checkpaymentPossiblity(false);
}
});
}, [label, amount, stripe, postStripeDonation]);
const displayRefreshError = (): void => {
onDonationStateChange({
redirecting: false,
processing: false,
success: false,
error: refreshErrorMessage
});
};
return (
<form className='wallets-form'>
{canMakePayment && paymentRequest && (
<PaymentRequestButtonElement
onClick={() => {
if (token) {
displayRefreshError();
}
}}
options={{
style: {
paymentRequestButton: {
type: 'default',
theme: theme === 'night' ? 'light' : 'dark',
height: '43px'
}
},
paymentRequest
}}
/>
)}
</form>
);
};
const InjectedCheckoutForm = (props: WrapperProps): JSX.Element => (
<ElementsConsumer>
{({ stripe }: { stripe: Stripe | null }) => (
<WalletsButton stripe={stripe} {...props} />
)}
</ElementsConsumer>
);
const WalletsWrapper = (props: WrapperProps): JSX.Element | null => {
if (!stripePublicKey) {
return null;
} else {
const stripePromise = loadStripe(stripePublicKey);
return (
<Elements stripe={stripePromise}>
<InjectedCheckoutForm {...props} />
</Elements>
);
}
};
export default WalletsWrapper;