Refined member account details to show any applied discounts

refs https://github.com/TryGhost/Team/issues/1195

- shows any applied discounts on subscription on account profile page
This commit is contained in:
Rishabh 2022-01-04 20:12:06 +05:30
parent cdd1c429df
commit 86a8abdf30
4 changed files with 83 additions and 7 deletions

View File

@ -476,6 +476,10 @@ const FrameStyles = `
color: var(--grey6);
}
.gh-portal-list-detail .old-price {
text-decoration: line-through;
}
.gh-portal-right-arrow {
line-height: 1;
color: var(--grey8);

View File

@ -3,9 +3,10 @@ import MemberAvatar from '../common/MemberGravatar';
import ActionButton from '../common/ActionButton';
import CloseButton from '../common/CloseButton';
import Switch from '../common/Switch';
import {getMemberSubscription, hasOnlyFreePlan, isComplimentaryMember} from '../../utils/helpers';
import {getMemberSubscription, getUpdatedOfferPrice, hasOnlyFreePlan, isComplimentaryMember} from '../../utils/helpers';
import {getDateString} from '../../utils/date-time';
import {ReactComponent as LoaderIcon} from '../../images/icons/loader.svg';
import {ReactComponent as OfferTagIcon} from '../../images/icons/offer-tag.svg';
import {useContext} from 'react';
const React = require('react');
@ -137,6 +138,25 @@ const UserHeader = () => {
);
};
function getOfferLabel({offer, price, subscriptionStartDate}) {
let offerLabel = '';
if (offer) {
const discountDuration = offer.duration;
let durationLabel = '';
if (discountDuration === 'forever') {
durationLabel = `Forever`;
} else if (discountDuration === 'repeating') {
const durationInMonths = offer.duration_in_months || 0;
let offerStartDate = new Date(subscriptionStartDate);
let offerEndDate = new Date(offerStartDate.setMonth(offerStartDate.getMonth() + durationInMonths));
durationLabel = `Ends ${getDateString(offerEndDate)}`;
}
offerLabel = `${getUpdatedOfferPrice({offer, price, useFormatted: true})}/${price.interval} - ${durationLabel}`;
}
return offerLabel;
}
const PaidAccountActions = () => {
const {member, site, onAction} = useContext(AppContext);
@ -155,19 +175,42 @@ const PaidAccountActions = () => {
}
};
const PlanLabel = ({price, isComplimentary}) => {
const PlanLabel = ({price, isComplimentary, subscription}) => {
const {
offer,
start_date: startDate
} = subscription;
let label = '';
if (price) {
const {amount = 0, currency, interval} = price;
label = `${Intl.NumberFormat('en', {currency, style: 'currency'}).format(amount / 100)}/${interval}`;
}
let offerLabelStr = getOfferLabel({price, offer, subscriptionStartDate: startDate});
if (isComplimentary) {
label = label ? `Complimentary (${label})` : `Complimentary`;
}
let oldPriceClassName = '';
if (offerLabelStr) {
oldPriceClassName = 'old-price';
}
const OfferLabel = () => {
if (offerLabelStr) {
return (
<p>
<OfferTagIcon style={{width: '12px', height: '9px', marginLeft: '-10px'}}/>
{offerLabelStr}
</p>
);
}
return null;
};
return (
<p>
{label}
</p>
<>
<p className={oldPriceClassName}>
{label}
</p>
<OfferLabel />
</>
);
};
@ -216,7 +259,6 @@ const PaidAccountActions = () => {
const isComplimentary = isComplimentaryMember({member});
if (subscription || isComplimentary) {
const {
plan,
price,
default_payment_card_last4: defaultCardLast4
} = subscription || {};
@ -225,7 +267,7 @@ const PaidAccountActions = () => {
<section>
<div className='gh-portal-list-detail'>
<h3>Plan</h3>
<PlanLabel plan={plan} price={price} isComplimentary={isComplimentary} />
<PlanLabel price={price} isComplimentary={isComplimentary} subscription={subscription} />
</div>
<PlanUpdateButton isComplimentary={isComplimentary} />
</section>

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><defs><style>.a{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}</style></defs>
<path d="M22.939 2.56V8.817C22.9391 9.61244 22.6232 10.3754 22.061 10.938L10.5 22.5C10.2187 22.7812 9.83721 22.9392 9.43946 22.9392C9.04172 22.9392 8.66026 22.7812 8.37896 22.5L1.49997 15.62C1.21876 15.3387 1.06079 14.9572 1.06079 14.5595C1.06079 14.1618 1.21876 13.7803 1.49997 13.499L13.061 1.938C13.6236 1.37572 14.3865 1.0599 15.182 1.06H21.439C21.8368 1.06 22.2183 1.21803 22.4996 1.49934C22.7809 1.78064 22.939 2.16217 22.939 2.56V2.56Z" class="a" />
<path d="M17.689 7.81C16.8605 7.81 16.189 7.13842 16.189 6.31C16.189 5.48157 16.8605 4.81 17.689 4.81C18.5174 4.81 19.189 5.48157 19.189 6.31C19.189 7.13842 18.5174 7.81 17.689 7.81Z" class="a" />
</svg>

After

Width:  |  Height:  |  Size: 893 B

View File

@ -502,3 +502,29 @@ export function getPriceIdFromPageQuery({site, pageQuery}) {
}
return null;
}
export const getOfferOffAmount = ({offer}) => {
if (offer.type === 'fixed') {
return `${getCurrencySymbol(offer.currency)}${offer.amount / 100}`;
} else if (offer.type === 'percent') {
return `${offer.amount}%`;
}
return '';
};
export const getUpdatedOfferPrice = ({offer, price, useFormatted = false}) => {
const originalAmount = price.amount;
let updatedAmount;
if (offer.type === 'fixed' && isSameCurrency(offer.currency, price.currency)) {
updatedAmount = ((originalAmount - offer.amount)) / 100;
updatedAmount = updatedAmount > 0 ? updatedAmount : 0;
} else if (offer.type === 'percent') {
updatedAmount = (originalAmount - ((originalAmount * offer.amount) / 100)) / 100;
} else {
updatedAmount = originalAmount / 100;
}
if (useFormatted) {
return Intl.NumberFormat('en', {currency: price?.currency, style: 'currency'}).format(updatedAmount);
}
return updatedAmount;
};