mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-18 10:00:55 -04:00
feat(client): ab test shorter block donations (#59616)
This commit is contained in:
1
client/src/assets/images/supporter-bear-block.svg
Normal file
1
client/src/assets/images/supporter-bear-block.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9.2 KiB |
@@ -6,6 +6,7 @@ import { closeDonationModal } from '../../redux/actions';
|
||||
import { PaymentContext } from '../../../../shared/config/donation-settings';
|
||||
import donationAnimation from '../../assets/images/donation-bear-animation.svg';
|
||||
import donationAnimationB from '../../assets/images/new-bear-animation.svg';
|
||||
import supporterBearBlock from '../../assets/images/supporter-bear-block.svg';
|
||||
import supporterBear from '../../assets/images/supporter-bear.svg';
|
||||
import callGA from '../../analytics/call-ga';
|
||||
import MultiTierDonationForm from './multi-tier-donation-form';
|
||||
@@ -19,13 +20,25 @@ type DonationModalBodyProps = {
|
||||
setCanClose: (canClose: boolean) => void;
|
||||
};
|
||||
|
||||
const Illustration = () => {
|
||||
const Illustration = ({
|
||||
donatableSectionRecentlyCompleted,
|
||||
useShortDonationBlocks
|
||||
}: {
|
||||
donatableSectionRecentlyCompleted: DonatableSectionRecentlyCompleted;
|
||||
useShortDonationBlocks: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const showNewBearIllustration =
|
||||
useShortDonationBlocks && donatableSectionRecentlyCompleted;
|
||||
return (
|
||||
<img
|
||||
alt={t('donate.flying-bear')}
|
||||
alt={
|
||||
showNewBearIllustration
|
||||
? t('bear-completion-alt')
|
||||
: t('donate.flying-bear')
|
||||
}
|
||||
id={'supporter-bear'}
|
||||
src={supporterBear}
|
||||
src={showNewBearIllustration ? supporterBearBlock : supporterBear}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -44,7 +57,6 @@ function ModalHeader({
|
||||
const { t } = useTranslation();
|
||||
const { section, superBlock, title } =
|
||||
donatableSectionRecentlyCompleted || {};
|
||||
|
||||
if (!showHeaderAndFooter || donationAttempted) {
|
||||
return null;
|
||||
} else if (!showForm) {
|
||||
@@ -196,6 +208,7 @@ const BecomeASupporterConfirmation = ({
|
||||
setShowHeaderAndFooter,
|
||||
handleProcessing,
|
||||
setShowForm,
|
||||
useShortDonationBlocks,
|
||||
donatableSectionRecentlyCompleted
|
||||
}: {
|
||||
donatableSectionRecentlyCompleted: DonatableSectionRecentlyCompleted;
|
||||
@@ -206,11 +219,15 @@ const BecomeASupporterConfirmation = ({
|
||||
setShowHeaderAndFooter: (arg: boolean) => void;
|
||||
handleProcessing: () => void;
|
||||
setShowForm: (arg: boolean) => void;
|
||||
useShortDonationBlocks: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<div className='no-delay-fade-in'>
|
||||
<div className='donation-icon-container'>
|
||||
<Illustration />
|
||||
<Illustration
|
||||
donatableSectionRecentlyCompleted={donatableSectionRecentlyCompleted}
|
||||
useShortDonationBlocks={useShortDonationBlocks}
|
||||
/>
|
||||
</div>
|
||||
<ModalHeader
|
||||
donatableSectionRecentlyCompleted={donatableSectionRecentlyCompleted}
|
||||
@@ -249,23 +266,34 @@ function DonationModalBody({
|
||||
const [isAnimationVisible, setIsAnimationVisible] = useState(true);
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
const [secondsRemaining, setSecondsRemaining] = useState(20);
|
||||
const useShortDonationBlocks = useFeature('short-donation-blocks').on;
|
||||
|
||||
const handleProcessing = () => {
|
||||
setDonationAttempted(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(() => {
|
||||
setSecondsRemaining(prevSeconds => prevSeconds - 1);
|
||||
}, 1000);
|
||||
|
||||
if (secondsRemaining <= 0) {
|
||||
let intervalId: NodeJS.Timeout;
|
||||
if (useShortDonationBlocks && donatableSectionRecentlyCompleted) {
|
||||
setIsAnimationVisible(false);
|
||||
setCanClose(true);
|
||||
clearInterval(intervalId);
|
||||
} else {
|
||||
intervalId = setInterval(() => {
|
||||
setSecondsRemaining(prevSeconds => prevSeconds - 1);
|
||||
}, 1000);
|
||||
if (secondsRemaining <= 0) {
|
||||
setIsAnimationVisible(false);
|
||||
setCanClose(true);
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}
|
||||
return () => clearInterval(intervalId);
|
||||
}, [secondsRemaining, setCanClose]);
|
||||
}, [
|
||||
secondsRemaining,
|
||||
setCanClose,
|
||||
donatableSectionRecentlyCompleted,
|
||||
useShortDonationBlocks
|
||||
]);
|
||||
|
||||
return (
|
||||
<Modal.Body borderless alignment='start'>
|
||||
@@ -284,6 +312,7 @@ function DonationModalBody({
|
||||
setShowHeaderAndFooter={setShowHeaderAndFooter}
|
||||
handleProcessing={handleProcessing}
|
||||
setShowForm={setShowForm}
|
||||
useShortDonationBlocks={useShortDonationBlocks}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
import { stringifyDonationEvents } from '../utils/analytics-strings';
|
||||
import { stripe } from '../utils/stripe';
|
||||
import { PaymentProvider } from '../../../shared/config/donation-settings';
|
||||
import { chapterBasedSuperBlocks } from '../../../shared/config/curriculum';
|
||||
import {
|
||||
getSessionChallengeData,
|
||||
saveCurrentCount
|
||||
@@ -60,7 +59,9 @@ function* showDonateModalSaga() {
|
||||
if (shouldShowModal) {
|
||||
yield delay(200);
|
||||
yield put(openDonationModal());
|
||||
sessionStorage.setItem(MODAL_SHOWN_KEY, Date.now());
|
||||
if (!donatableSectionRecentlyCompleted) {
|
||||
sessionStorage.setItem(MODAL_SHOWN_KEY, Date.now());
|
||||
}
|
||||
yield take(appTypes.closeDonationModal);
|
||||
if (!donatableSectionRecentlyCompleted) {
|
||||
yield call(saveCurrentCount);
|
||||
|
||||
Reference in New Issue
Block a user