TelegramPWA/src/components/main/premium/GiftPremiumModal.tsx
2023-12-28 14:38:10 +01:00

179 lines
5.2 KiB
TypeScript

import type { FC } from '../../../lib/teact/teact';
import React, {
memo, useCallback, useEffect, useMemo, useState,
} from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global';
import type { ApiPremiumGiftOption, ApiUser } from '../../../api/types';
import { getUserFirstOrLastName } from '../../../global/helpers';
import {
selectTabState,
selectUser,
selectUserFullInfo,
} from '../../../global/selectors';
import { formatCurrency } from '../../../util/formatCurrency';
import renderText from '../../common/helpers/renderText';
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
import useLang from '../../../hooks/useLang';
import Avatar from '../../common/Avatar';
import Button from '../../ui/Button';
import Link from '../../ui/Link';
import Modal from '../../ui/Modal';
import PremiumSubscriptionOption from './PremiumSubscriptionOption';
import styles from './GiftPremiumModal.module.scss';
export type OwnProps = {
isOpen?: boolean;
};
type StateProps = {
user?: ApiUser;
gifts?: ApiPremiumGiftOption[];
monthlyCurrency?: string;
monthlyAmount?: number;
};
const GiftPremiumModal: FC<OwnProps & StateProps> = ({
isOpen,
user,
gifts,
monthlyCurrency,
monthlyAmount,
}) => {
const { openPremiumModal, closeGiftPremiumModal, openUrl } = getActions();
const lang = useLang();
const renderedUser = useCurrentOrPrev(user, true);
const renderedGifts = useCurrentOrPrev(gifts, true);
const [selectedOption, setSelectedOption] = useState<number | undefined>();
const firstGift = renderedGifts?.[0];
const fullMonthlyAmount = useMemo(() => {
if (!renderedGifts || renderedGifts.length === 0 || !firstGift) {
return undefined;
}
const cheaperGift = renderedGifts.reduce((acc, gift) => {
return gift.amount < firstGift?.amount ? gift : firstGift;
}, firstGift);
return cheaperGift.currency === monthlyCurrency && monthlyAmount
? monthlyAmount
: Math.floor(cheaperGift.amount / cheaperGift.months);
}, [firstGift, renderedGifts, monthlyAmount, monthlyCurrency]);
useEffect(() => {
if (isOpen) {
setSelectedOption(firstGift?.months);
}
}, [firstGift?.months, isOpen]);
const selectedGift = useMemo(() => {
return renderedGifts?.find((gift) => gift.months === selectedOption);
}, [renderedGifts, selectedOption]);
const handleSubmit = useCallback(() => {
if (!selectedGift) {
return;
}
closeGiftPremiumModal();
openUrl({ url: selectedGift.botUrl });
}, [closeGiftPremiumModal, openUrl, selectedGift]);
const handlePremiumClick = useCallback(() => {
openPremiumModal();
}, [openPremiumModal]);
function renderPremiumFeaturesLink() {
const info = lang('GiftPremiumListFeaturesAndTerms');
// Translation hack for rendering component inside string
const parts = info.match(/([^*]*)\*([^*]+)\*(.*)/);
if (!parts || parts.length < 4) {
return undefined;
}
return (
<p className={styles.premiumFeatures}>
{parts[1]}
<Link isPrimary onClick={handlePremiumClick}>{parts[2]}</Link>
{parts[3]}
</p>
);
}
return (
<Modal
onClose={closeGiftPremiumModal}
isOpen={isOpen}
className={styles.modalDialog}
>
<div className="custom-scroll">
<Button
round
size="smaller"
className={styles.closeButton}
color="translucent"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => closeGiftPremiumModal()}
ariaLabel={lang('Close')}
>
<i className="icon icon-close" />
</Button>
<Avatar
peer={renderedUser}
size="jumbo"
className={styles.avatar}
/>
<h2 className={styles.headerText}>
{lang('GiftTelegramPremiumTitle')}
</h2>
<p className={styles.description}>
{renderText(
lang('GiftTelegramPremiumDescription', getUserFirstOrLastName(renderedUser)),
['emoji', 'simple_markdown'],
)}
</p>
<div className={styles.options}>
{renderedGifts?.map((gift) => (
<PremiumSubscriptionOption
key={gift.amount}
option={gift}
fullMonthlyAmount={fullMonthlyAmount}
checked={gift.months === selectedOption}
onChange={setSelectedOption}
/>
))}
</div>
{renderPremiumFeaturesLink()}
</div>
<Button className={styles.button} isShiny disabled={!selectedOption} onClick={handleSubmit}>
{lang(
'GiftSubscriptionFor',
selectedGift && formatCurrency(Number(selectedGift.amount), selectedGift.currency, lang.code),
)}
</Button>
</Modal>
);
};
export default memo(withGlobal<OwnProps>((global): StateProps => {
const { forUserId, monthlyCurrency, monthlyAmount } = selectTabState(global).giftPremiumModal || {};
const user = forUserId ? selectUser(global, forUserId) : undefined;
const gifts = user ? selectUserFullInfo(global, user.id)?.premiumGifts : undefined;
return {
user,
gifts,
monthlyCurrency,
monthlyAmount: monthlyAmount ? Number(monthlyAmount) : undefined,
};
})(GiftPremiumModal));