feat: turn donation modal element into react components (#51670)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Muhammed Mustafa
2023-10-02 13:50:15 +03:00
committed by GitHub
co-authored by Oliver Eyton-Williams
parent 7faf636051
commit 606ca74deb
+303 -118
View File
@@ -12,7 +12,8 @@ import {
PaymentContext,
subscriptionAmounts,
defaultDonation,
defaultTierAmount
defaultTierAmount,
type DonationAmount
} from '../../../../shared/config/donation-settings';
import BearProgressModal from '../../assets/images/components/bear-progress-modal';
import BearBlockCompletion from '../../assets/images/components/bear-block-completion-modal';
@@ -56,7 +57,7 @@ type DonateModalProps = {
show: boolean;
};
const RenderIlustration = ({
const Ilustration = ({
recentlyClaimedBlock
}: {
recentlyClaimedBlock: RecentlyClaimedBlock;
@@ -74,78 +75,20 @@ function getctaNumberBetween1To10() {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function DonateModal({
show,
closeDonationModal,
executeGA,
location,
function ModalHeader({
closeLabel,
ctaNumber,
showMultiTier,
recentlyClaimedBlock
}: DonateModalProps): JSX.Element {
const [closeLabel, setCloseLabel] = useState(false);
const [ctaNumber, setCtaNumber] = useState(0);
const [isDisabled, setIsDisabled] = useState(true);
const [showSkipButton, setShowSkipButton] = useState(false);
const [showDonateForm, setShowDonateForm] = useState(true);
const [donationAmount, setDonationAmount] = useState(
defaultDonation.donationAmount
);
const loadElementsIndividually = useFeature('load_elements_individually').on;
const showMultiTier = useFeature('multi-tier').on;
}: {
closeLabel: boolean;
ctaNumber: number;
showMultiTier: boolean;
recentlyClaimedBlock: RecentlyClaimedBlock;
}) {
const { t } = useTranslation();
// test wheather the conversions are being distributed properly
useFeature('aa-test-in-component');
const handleProcessing = () => {
setCloseLabel(true);
};
useEffect(() => {
if (loadElementsIndividually) {
const timer = setTimeout(() => {
setIsDisabled(false);
setShowSkipButton(true);
}, 4000);
return () => clearTimeout(timer);
} else {
setIsDisabled(false);
setShowSkipButton(true);
}
}, [loadElementsIndividually]);
useEffect(() => {
if (show) {
void playTone('donation');
executeGA({ event: 'pageview', pagePath: '/donation-modal' });
executeGA({
event: 'donation_view',
action: `Displayed ${
recentlyClaimedBlock !== null ? 'Block' : 'Progress'
} Donation Modal`
});
}
}, [show, recentlyClaimedBlock, executeGA]);
useEffect(() => {
if (show) setCtaNumber(getctaNumberBetween1To10());
}, [show]);
useEffect(() => {
if (showMultiTier) {
setShowDonateForm(false);
setDonationAmount(defaultTierAmount);
}
}, [showMultiTier]);
const handleModalHide = () => {
// If modal is open on a SuperBlock page
if (isLocationSuperBlock(location)) {
goToAnchor('claim-cert-block');
}
};
const modalHeader = (
<div className=' text-center block-modal-text'>
return (
<div className='text-center block-modal-text'>
<Row>
{!closeLabel && (
<Col sm={10} smOffset={1} xs={12}>
@@ -169,37 +112,27 @@ function DonateModal({
<Spacer size='small' />
</div>
);
}
const closeButtonRow = (
<>
<Row>
<Col
sm={4}
smOffset={4}
xs={8}
xsOffset={2}
className={showSkipButton ? 'no-delay-fade-in' : 'no-opacity'}
>
<Button
bsSize='sm'
bsStyle='primary'
className='btn-link close-button'
onClick={closeDonationModal}
tabIndex='0'
disabled={isDisabled}
>
{closeLabel ? t('buttons.close') : t('buttons.ask-later')}
</Button>
</Col>
</Row>
</>
);
const selectionTabs = (
function SelectionTabs({
loadElementsIndividually,
donationAmount,
setDonationAmount,
setShowDonateForm
}: {
loadElementsIndividually: boolean;
donationAmount: DonationAmount;
setDonationAmount: React.Dispatch<React.SetStateAction<DonationAmount>>;
setShowDonateForm: React.Dispatch<React.SetStateAction<boolean>>;
}) {
const { t } = useTranslation();
return (
<Row className={'donate-btn-group'}>
<Col
xs={12}
className={loadElementsIndividually && 'two-seconds-delay-fade-in'}
{...(loadElementsIndividually && {
className: 'two-seconds-delay-fade-in'
})}
>
<b>
{t('donate.confirm-monthly', {
@@ -255,12 +188,114 @@ function DonateModal({
</Col>
</Row>
);
}
const donationFormRow = (
function CloseButtonRow({
showSkipButton,
isDisabled,
closeLabel,
closeDonationModal
}: {
showSkipButton: boolean;
isDisabled: boolean;
closeLabel: boolean;
closeDonationModal: () => void;
}) {
const { t } = useTranslation();
return (
<Row>
<Col
sm={4}
smOffset={4}
xs={8}
xsOffset={2}
className={showSkipButton ? 'no-delay-fade-in' : 'no-opacity'}
>
<Button
bsSize='sm'
bsStyle='primary'
className='btn-link close-button'
onClick={closeDonationModal}
tabIndex='0'
disabled={isDisabled}
>
{closeLabel ? t('buttons.close') : t('buttons.ask-later')}
</Button>
</Col>
</Row>
);
}
function DonationBody({
closeLabel,
ctaNumber,
showMultiTier,
recentlyClaimedBlock,
donationAmount,
loadElementsIndividually,
handleProcessing,
setShowDonateForm,
closeDonationModal,
isDisabled,
showSkipButton
}: {
closeLabel: boolean;
ctaNumber: number;
showMultiTier: boolean;
recentlyClaimedBlock: RecentlyClaimedBlock;
donationAmount: DonationAmount;
loadElementsIndividually: boolean;
handleProcessing: () => void;
setShowDonateForm: React.Dispatch<React.SetStateAction<boolean>>;
closeDonationModal: () => void;
isDisabled: boolean;
showSkipButton: boolean;
}) {
return (
<>
<ModalHeader
closeLabel={closeLabel}
ctaNumber={ctaNumber}
recentlyClaimedBlock={recentlyClaimedBlock}
showMultiTier={showMultiTier}
/>
<DonationFormRow
donationAmount={donationAmount}
handleProcessing={handleProcessing}
showMultiTier={showMultiTier}
loadElementsIndividually={loadElementsIndividually}
setShowDonateForm={setShowDonateForm}
/>
<CloseButtonRow
closeDonationModal={closeDonationModal}
closeLabel={closeLabel}
isDisabled={isDisabled}
showSkipButton={showSkipButton}
/>
</>
);
}
function DonationFormRow({
handleProcessing,
loadElementsIndividually,
showMultiTier,
setShowDonateForm,
donationAmount
}: {
handleProcessing: () => void;
loadElementsIndividually: boolean;
showMultiTier: boolean;
setShowDonateForm: React.Dispatch<React.SetStateAction<boolean>>;
donationAmount: DonationAmount;
}) {
return (
<Row>
<Col
xs={12}
className={loadElementsIndividually && 'two-seconds-delay-fade-in'}
{...(loadElementsIndividually && {
className: 'two-seconds-delay-fade-in'
})}
>
<DonateForm
handleProcessing={handleProcessing}
@@ -275,28 +310,148 @@ function DonateModal({
</Col>
</Row>
);
}
const multiTierModalBody = (
function MultiTierDonationBody({
closeLabel,
ctaNumber,
showMultiTier,
recentlyClaimedBlock,
donationAmount,
loadElementsIndividually,
setDonationAmount,
setShowDonateForm,
closeDonationModal,
isDisabled,
showSkipButton,
showDonateForm,
handleProcessing
}: {
closeLabel: boolean;
ctaNumber: number;
showMultiTier: boolean;
recentlyClaimedBlock: RecentlyClaimedBlock;
donationAmount: DonationAmount;
loadElementsIndividually: boolean;
setDonationAmount: React.Dispatch<React.SetStateAction<DonationAmount>>;
setShowDonateForm: React.Dispatch<React.SetStateAction<boolean>>;
closeDonationModal: () => void;
isDisabled: boolean;
showSkipButton: boolean;
showDonateForm: boolean;
handleProcessing: () => void;
}) {
return (
<>
<div className={showDonateForm ? 'hide' : ''}>
{modalHeader}
{selectionTabs}
{closeButtonRow}
<div {...(showDonateForm && { className: 'hide' })}>
<ModalHeader
closeLabel={closeLabel}
ctaNumber={ctaNumber}
recentlyClaimedBlock={recentlyClaimedBlock}
showMultiTier={showMultiTier}
/>
<SelectionTabs
donationAmount={donationAmount}
loadElementsIndividually={loadElementsIndividually}
setDonationAmount={setDonationAmount}
setShowDonateForm={setShowDonateForm}
/>
<CloseButtonRow
closeDonationModal={closeDonationModal}
closeLabel={closeLabel}
isDisabled={isDisabled}
showSkipButton={showSkipButton}
/>
</div>
<div className={!showDonateForm ? 'hide' : ''}>
{donationFormRow}
{closeLabel && closeButtonRow}
<div {...(!showDonateForm && { className: 'hide' })}>
<DonationFormRow
donationAmount={donationAmount}
handleProcessing={handleProcessing}
showMultiTier={showMultiTier}
loadElementsIndividually={loadElementsIndividually}
setShowDonateForm={setShowDonateForm}
/>
{closeLabel && (
<CloseButtonRow
closeDonationModal={closeDonationModal}
closeLabel={closeLabel}
isDisabled={isDisabled}
showSkipButton={showSkipButton}
/>
)}
</div>
</>
);
}
const defaultModalBody = (
<>
{modalHeader}
{donationFormRow}
{closeButtonRow}
</>
function DonateModal({
show,
closeDonationModal,
executeGA,
location,
recentlyClaimedBlock
}: DonateModalProps): JSX.Element {
const [closeLabel, setCloseLabel] = useState(false);
const [ctaNumber, setCtaNumber] = useState(0);
const [isDisabled, setIsDisabled] = useState(true);
const [showSkipButton, setShowSkipButton] = useState(false);
const [showDonateForm, setShowDonateForm] = useState(true);
const [donationAmount, setDonationAmount] = useState(
defaultDonation.donationAmount
);
const loadElementsIndividually = useFeature('load_elements_individually').on;
const showMultiTier = useFeature('multi-tier').on;
// test wheather the conversions are being distributed properly
useFeature('aa-test-in-component');
const handleProcessing = () => {
setCloseLabel(true);
};
useEffect(() => {
if (loadElementsIndividually) {
const timer = setTimeout(() => {
setIsDisabled(false);
setShowSkipButton(true);
}, 4000);
return () => clearTimeout(timer);
} else {
setIsDisabled(false);
setShowSkipButton(true);
}
}, [loadElementsIndividually]);
useEffect(() => {
if (show) {
void playTone('donation');
executeGA({ event: 'pageview', pagePath: '/donation-modal' });
executeGA({
event: 'donation_view',
action: `Displayed ${
recentlyClaimedBlock !== null ? 'Block' : 'Progress'
} Donation Modal`
});
}
}, [show, recentlyClaimedBlock, executeGA]);
useEffect(() => {
if (show) setCtaNumber(getctaNumberBetween1To10());
}, [show]);
useEffect(() => {
if (showMultiTier) {
setShowDonateForm(false);
setDonationAmount(defaultTierAmount);
}
}, [showMultiTier]);
const handleModalHide = () => {
// If modal is open on a SuperBlock page
if (isLocationSuperBlock(location)) {
goToAnchor('claim-cert-block');
}
};
return (
<Modal
@@ -305,11 +460,41 @@ function DonateModal({
onExited={handleModalHide}
show={show}
>
<Modal.Body className={'no-delay-fade-in'}>
<Modal.Body className='no-delay-fade-in'>
<div className='donation-icon-container'>
<RenderIlustration recentlyClaimedBlock={recentlyClaimedBlock} />
<Ilustration recentlyClaimedBlock={recentlyClaimedBlock} />
</div>
{showMultiTier ? multiTierModalBody : defaultModalBody}
{showMultiTier ? (
<MultiTierDonationBody
recentlyClaimedBlock={recentlyClaimedBlock}
setDonationAmount={setDonationAmount}
setShowDonateForm={setShowDonateForm}
showDonateForm={showDonateForm}
showMultiTier={showMultiTier}
showSkipButton={showSkipButton}
closeDonationModal={closeDonationModal}
closeLabel={closeLabel}
ctaNumber={ctaNumber}
donationAmount={donationAmount}
handleProcessing={handleProcessing}
isDisabled={isDisabled}
loadElementsIndividually={loadElementsIndividually}
/>
) : (
<DonationBody
closeDonationModal={closeDonationModal}
closeLabel={closeLabel}
ctaNumber={ctaNumber}
donationAmount={donationAmount}
isDisabled={isDisabled}
handleProcessing={handleProcessing}
loadElementsIndividually={loadElementsIndividually}
recentlyClaimedBlock={recentlyClaimedBlock}
setShowDonateForm={setShowDonateForm}
showMultiTier={showMultiTier}
showSkipButton={showSkipButton}
/>
)}
</Modal.Body>
</Modal>
);