feat: a/b test lock icon (#45499)

* feat: a/b test

* Update client/i18n/locales/english/translations.json

* Apply suggestions from code review
This commit is contained in:
Ahmad Abdolsaheb
2022-03-22 19:28:41 +03:00
committed by GitHub
parent 4d620dea1a
commit 94650964c4
9 changed files with 39 additions and 94 deletions

View File

@@ -52,7 +52,6 @@
"@reach/router": "1.3.4",
"@stripe/react-stripe-js": "1.7.0",
"@stripe/stripe-js": "1.25.0",
"@types/canvas-confetti": "1.4.2",
"@types/react-scrollable-anchor": "0.6.1",
"algoliasearch": "4.13.0",
"assert": "2.0.0",
@@ -61,7 +60,6 @@
"bezier-easing": "2.1.0",
"browser-cookies": "1.2.0",
"buffer": "6.0.3",
"canvas-confetti": "1.5.1",
"chai": "4.3.6",
"crypto-browserify": "3.12.0",
"date-fns": "2.27.0",

View File

@@ -23,7 +23,8 @@ import {
defaultDonationFormState,
userSelector,
postChargeStripe,
postChargeStripeCard
postChargeStripeCard,
isAVariantSelector
} from '../../redux';
import Spacer from '../helpers/spacer';
import { Themes } from '../settings/theme';
@@ -33,6 +34,7 @@ import type { AddDonationData } from './paypal-button';
import PaypalButton from './paypal-button';
import StripeCardForm, { HandleAuthentication } from './stripe-card-form';
import WalletsWrapper from './walletsButton';
import SecurityLockIcon from './security-lock-icon';
import './donation.css';
@@ -78,6 +80,7 @@ type DonateFormProps = {
) => string;
theme: Themes;
updateDonationFormState: (state: AddDonationData) => unknown;
isAVariant: boolean;
};
const mapStateToProps = createSelector(
@@ -86,19 +89,22 @@ const mapStateToProps = createSelector(
isDonatingSelector,
donationFormStateSelector,
userSelector,
isAVariantSelector,
(
showLoading: DonateFormProps['showLoading'],
isSignedIn: DonateFormProps['isSignedIn'],
isDonating: DonateFormProps['isDonating'],
donationFormState: DonateFormState,
{ email, theme }: { email: string; theme: Themes }
{ email, theme }: { email: string; theme: Themes },
isAVariant: boolean
) => ({
isSignedIn,
isDonating,
showLoading,
donationFormState,
email,
theme
theme,
isAVariant
})
);
@@ -315,7 +321,8 @@ class DonateForm extends Component<DonateFormProps, DonateFormComponentState> {
t,
isMinimalForm,
isSignedIn,
isDonating
isDonating,
isAVariant
} = this.props;
const priorityTheme = defaultTheme ? defaultTheme : theme;
const isOneTime = donationDuration === 'onetime';
@@ -328,6 +335,7 @@ class DonateForm extends Component<DonateFormProps, DonateFormComponentState> {
return (
<>
<b className={isMinimalForm ? 'donation-label-modal' : ''}>
{isAVariant === false && <SecurityLockIcon />}
{this.getDonationButtonLabel()}:
</b>
<Spacer />
@@ -366,6 +374,7 @@ class DonateForm extends Component<DonateFormProps, DonateFormComponentState> {
processing={processing}
t={t}
theme={priorityTheme}
isAVariant={isAVariant}
/>
</>
)}

View File

@@ -334,6 +334,10 @@ li.disabled > a {
height: 22px;
}
.confirm-donation-btn svg.svg-inline--fa.fa-lock {
margin-bottom: 2px;
}
@media screen and (min-width: 355px) {
.form-payment-methods {
height: 30px;

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { faLock } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const SecurityLockIcon = (): JSX.Element => {
return (
<>
<FontAwesomeIcon icon={faLock} />
&nbsp;&nbsp;
</>
);
};
export default SecurityLockIcon;

View File

@@ -17,6 +17,7 @@ import React, { useState } from 'react';
import envData from '../../../../config/env.json';
import { Themes } from '../settings/theme';
import { AddDonationData } from './paypal-button';
import SecurityLockIcon from './security-lock-icon';
const { stripePublicKey }: { stripePublicKey: string | null } = envData;
@@ -34,6 +35,7 @@ interface FormPropTypes {
t: (label: string) => string;
theme: Themes;
processing: boolean;
isAVariant: boolean;
}
interface Element {
@@ -49,7 +51,8 @@ const StripeCardForm = ({
t,
onDonationStateChange,
postStripeCardDonation,
processing
processing,
isAVariant
}: FormPropTypes): JSX.Element => {
const [isSubmissionValid, setSubmissionValidity] = useState(true);
const [isTokenizing, setTokenizing] = useState(false);
@@ -167,7 +170,8 @@ const StripeCardForm = ({
disabled={!stripe || !elements || isSubmitting}
type='submit'
>
Donate
{isAVariant === false && <SecurityLockIcon />}
{t('buttons.donate')}
</Button>
</Form>
);

View File

@@ -8,7 +8,6 @@ import {
take
} from 'redux-saga/effects';
import i18next from 'i18next';
import { fireConfetti } from '../utils/fire-confetti';
import {
addDonation,
@@ -28,8 +27,7 @@ import {
postChargeStripeComplete,
postChargeStripeError,
postChargeStripeCardComplete,
postChargeStripeCardError,
isAVariantSelector
postChargeStripeCardError
} from './';
const defaultDonationErrorMessage = i18next.t('donate.error-2');
@@ -40,12 +38,6 @@ function* showDonateModalSaga() {
yield delay(200);
const recentlyClaimedBlock = yield select(recentlyClaimedBlockSelector);
yield put(openDonationModal());
if (recentlyClaimedBlock) {
const isAVariant = yield select(isAVariantSelector);
if (isAVariant === false) {
fireConfetti();
}
}
yield take(appTypes.closeDonationModal);
if (recentlyClaimedBlock) {
yield put(preventBlockDonationRequests());

View File

@@ -1,48 +0,0 @@
import confetti from 'canvas-confetti';
export const fireConfetti = () => {
const count = 200;
const defaults = {
origin: { y: 0.7 },
zIndex: 10000
};
function fire(
particleRatio: number,
opts: {
spread?: number;
startVelocity?: number;
decay?: number;
scalar?: number;
}
) {
confetti(
Object.assign({}, defaults, opts, {
particleCount: Math.floor(count * particleRatio)
})
)?.catch(err => console.log(err));
}
fire(0.25, {
spread: 26,
startVelocity: 55
});
fire(0.2, {
spread: 60
});
fire(0.35, {
spread: 100,
decay: 0.91,
scalar: 0.8
});
fire(0.1, {
spread: 120,
startVelocity: 25,
decay: 0.92,
scalar: 1.2
});
fire(0.1, {
spread: 120,
startVelocity: 45
});
};