181 lines
5.2 KiB
TypeScript

import type { FC } from '../../lib/teact/teact';
import React, { memo } from '../../lib/teact/teact';
import type { LangCode, Price } from '../../types';
import type { ApiChat, ApiWebDocument } from '../../api/types';
import { getWebDocumentHash } from '../../global/helpers';
import { formatCurrency } from '../../util/formatCurrency';
import buildClassName from '../../util/buildClassName';
import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang';
import useMedia from '../../hooks/useMedia';
import Checkbox from '../ui/Checkbox';
import Skeleton from '../ui/Skeleton';
import SafeLink from '../common/SafeLink';
import styles from './Checkout.module.scss';
export type OwnProps = {
chat?: ApiChat;
invoiceContent?: {
title?: string;
text?: string;
photo?: ApiWebDocument;
isRecurring?: boolean;
recurringTermsUrl?: string;
};
checkoutInfo?: {
paymentMethod?: string;
paymentProvider?: string;
shippingAddress?: string;
name?: string;
phone?: string;
shippingMethod?: string;
};
prices?: Price[];
totalPrice?: number;
shippingPrices?: Price[];
currency: string;
isTosAccepted?: boolean;
onAcceptTos?: (isAccepted: boolean) => void;
};
const Checkout: FC<OwnProps> = ({
chat,
invoiceContent,
prices,
shippingPrices,
checkoutInfo,
currency,
totalPrice,
isTosAccepted,
onAcceptTos,
}) => {
const lang = useLang();
const {
photo, title, text, isRecurring, recurringTermsUrl,
} = invoiceContent || {};
const {
paymentMethod,
paymentProvider,
shippingAddress,
name,
phone,
shippingMethod,
} = (checkoutInfo || {});
const photoUrl = useMedia(getWebDocumentHash(photo));
function renderTosLink(url: string, isRtl?: boolean) {
const langString = lang('PaymentCheckoutAcceptRecurrent', chat?.title);
const langStringSplit = langString.split('*');
return (
<>
{langStringSplit[0]}
<SafeLink
url={url}
text=""
isRtl={isRtl}
>
{langStringSplit[1]}
</SafeLink>
{langStringSplit.slice(2)}
</>
);
}
function renderTos(url: string) {
return (
<Checkbox
label={renderTosLink(url, lang.isRtl)}
name="checkout_tos"
checked={Boolean(isTosAccepted)}
className={styles.tosCheckbox}
tabIndex={0}
onCheck={onAcceptTos}
/>
);
}
return (
<div className={styles.root}>
<div className={styles.description}>
{photoUrl && <img className={styles.checkoutPicture} src={photoUrl} alt="" />}
{!photoUrl && photo && (
<Skeleton
width={photo.dimensions?.width}
height={photo.dimensions?.height}
className={styles.checkoutPicture}
forceAspectRatio
/>
)}
<div className={styles.text}>
<h5 className={styles.checkoutTitle}>{title}</h5>
{text && <div className={styles.checkoutDescription}>{renderText(text, ['br', 'links', 'emoji'])}</div>}
</div>
</div>
<div className={styles.priceInfo}>
{prices && prices.map((item) => (
renderPaymentItem(lang.code, item.label, item.amount, currency)
))}
{shippingPrices && shippingPrices.map((item) => (
renderPaymentItem(lang.code, item.label, item.amount, currency)
))}
{totalPrice !== undefined && (
renderPaymentItem(lang.code, lang('Checkout.TotalAmount'), totalPrice, currency, true)
)}
</div>
<div className={styles.invoiceInfo}>
{paymentMethod && renderCheckoutItem('icon-card', paymentMethod, lang('PaymentCheckoutMethod'))}
{paymentProvider && renderCheckoutItem(
buildClassName(styles.provider, styles[paymentProvider.toLowerCase()]),
paymentProvider,
lang('PaymentCheckoutProvider'),
)}
{shippingAddress && renderCheckoutItem('icon-location', shippingAddress, lang('PaymentShippingAddress'))}
{name && renderCheckoutItem('icon-user', name, lang('PaymentCheckoutName'))}
{phone && renderCheckoutItem('icon-phone', phone, lang('PaymentCheckoutPhoneNumber'))}
{shippingMethod && renderCheckoutItem('icon-truck', shippingMethod, lang('PaymentCheckoutShippingMethod'))}
{isRecurring && renderTos(recurringTermsUrl!)}
</div>
</div>
);
};
function renderPaymentItem(
langCode: LangCode | undefined, title: string, value: number, currency: string, main = false,
) {
return (
<div className={buildClassName(styles.priceInfoItem, main && styles.priceInfoItemMain)}>
<div className={styles.priceInfoItemTitle}>
{title}
</div>
<div>
{formatCurrency(value, currency, langCode)}
</div>
</div>
);
}
function renderCheckoutItem(icon: string, title: string, data: string) {
return (
<div className={styles.checkoutInfoItem}>
<i className={buildClassName(icon, styles.checkoutInfoItemIcon)}> </i>
<div className={styles.checkoutInfoItemInfo}>
<div className={styles.checkoutInfoItemInfoTitle}>
{title}
</div>
<p className={styles.checkoutInfoItemInfoData}>
{data}
</p>
</div>
</div>
);
}
export default memo(Checkout);