94 lines
3.2 KiB
JavaScript
Executable file
94 lines
3.2 KiB
JavaScript
Executable file
import React from 'react';
|
|
import i18n from '../../i18n';
|
|
import FormTitle, {Tags} from '../../uikit/form/FormTitle';
|
|
import FormText from '../../uikit/form/FormText';
|
|
import FormDivider from '../../uikit/form/FormDivider';
|
|
import type {BillingItem} from '../../flow/Action';
|
|
import {CurrencySymbols, PaymentStatusTypes} from '../../Constants';
|
|
|
|
const PaymentTypeLabels = {
|
|
[PaymentStatusTypes.PENDING]: i18n.Messages.PENDING,
|
|
// In partial refunds, state is still completed. Normally we never show a
|
|
// label for completed, however in this case we need to show a refunded label
|
|
[PaymentStatusTypes.COMPLETED]: i18n.Messages.REFUND,
|
|
[PaymentStatusTypes.FAILED]: i18n.Messages.FAILED,
|
|
[PaymentStatusTypes.REVERSED]: i18n.Messages.REVERSED,
|
|
[PaymentStatusTypes.REFUNDED]: i18n.Messages.REFUND,
|
|
};
|
|
|
|
const PaymentTypeClasses = {
|
|
[PaymentStatusTypes.PENDING]: 'pending',
|
|
[PaymentStatusTypes.COMPLETED]: 'completed',
|
|
[PaymentStatusTypes.FAILED]: 'failed',
|
|
[PaymentStatusTypes.REVERSED]: 'reversed',
|
|
[PaymentStatusTypes.REFUNDED]: 'refunded',
|
|
};
|
|
|
|
function formatMoney(amount) {
|
|
amount = amount + '';
|
|
return `${CurrencySymbols.USD}${amount.substring(0, amount.length - 2)}.${amount.substring(amount.length - 2)}`;
|
|
}
|
|
|
|
class BillingHistory extends React.PureComponent {
|
|
renderBillingItem(item: BillingItem, index: number) {
|
|
const {locale} = this.props;
|
|
const {status} = item;
|
|
if (status === PaymentStatusTypes.PENDING) {
|
|
return null;
|
|
}
|
|
const date = new Date(item.created_at);
|
|
|
|
let billingLabel;
|
|
if (status !== PaymentStatusTypes.COMPLETED || (status === PaymentStatusTypes.COMPLETED && item.amount_refunded)) {
|
|
billingLabel = <span className="billing-label">{PaymentTypeLabels[status]}</span>;
|
|
}
|
|
|
|
let amountRefunded;
|
|
if (item.amount_refunded) {
|
|
amountRefunded = (
|
|
<span className="refunded-amount">
|
|
{`(+${formatMoney(item.amount_refunded)})`}
|
|
</span>
|
|
);
|
|
}
|
|
return (
|
|
<li key={`bill-${index}`} className={PaymentTypeClasses[item.status]}>
|
|
<FormDivider className="bill-row-divider" lineOnly />
|
|
<FormText className="date">{date.toLocaleDateString(locale)}</FormText>
|
|
<FormText className="description">{item.description}</FormText>
|
|
<div className="payment-details">
|
|
{billingLabel}
|
|
{amountRefunded}
|
|
<FormText className="amount">{formatMoney(item.amount)}</FormText>
|
|
</div>
|
|
</li>
|
|
);
|
|
}
|
|
|
|
render() {
|
|
const billingHistoryElements = this.props.billingHistory.map(this.renderBillingItem, this);
|
|
billingHistoryElements.unshift(
|
|
<li key="bill-header" className="header-row">
|
|
<FormTitle className="date">{i18n.Messages.DATE}</FormTitle>
|
|
<FormTitle className="description">{i18n.Messages.DESCRIPTION}</FormTitle>
|
|
<FormTitle className="payment-details">{i18n.Messages.AMOUNT}</FormTitle>
|
|
</li>
|
|
);
|
|
|
|
return (
|
|
<div className="billing-history">
|
|
<FormTitle tag={Tags.H2}>{i18n.Messages.BILLING_HISTORY}</FormTitle>
|
|
<ol className="billing-history-list">
|
|
{billingHistoryElements}
|
|
</ol>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default BillingHistory;
|
|
|
|
|
|
|
|
// WEBPACK FOOTER //
|
|
// ./discord_app/components/premium/BillingHistory.js
|