mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Fixed currency display on AdminX tiers list (#17341)
refs https://github.com/TryGhost/Product/issues/3580
This commit is contained in:
parent
48dfb6ede3
commit
8f6bf61359
3 changed files with 31 additions and 16 deletions
|
@ -14,6 +14,7 @@ import useForm from '../../../../hooks/useForm';
|
|||
import useRouting from '../../../../hooks/useRouting';
|
||||
import useSortableIndexedList from '../../../../hooks/useSortableIndexedList';
|
||||
import {Tier} from '../../../../types/api';
|
||||
import {currencyFromDecimal, currencyToDecimal} from '../../../../utils/currency';
|
||||
import {useTiers} from '../../../providers/ServiceProvider';
|
||||
|
||||
interface TierDetailModalProps {
|
||||
|
@ -34,16 +35,16 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
|||
const {formState, updateForm, handleSave} = useForm<TierFormState>({
|
||||
initialState: {
|
||||
...(tier || {}),
|
||||
monthly_price: tier?.monthly_price?.toString() || '',
|
||||
yearly_price: tier?.monthly_price?.toString() || '',
|
||||
monthly_price: tier?.monthly_price ? currencyToDecimal(tier.monthly_price).toString() : '',
|
||||
yearly_price: tier?.yearly_price ? currencyToDecimal(tier.yearly_price).toString() : '',
|
||||
trial_days: tier?.trial_days?.toString() || ''
|
||||
},
|
||||
onSave: async () => {
|
||||
const values = {
|
||||
...formState,
|
||||
monthly_price: parseFloat(formState.monthly_price),
|
||||
yearly_price: parseFloat(formState.yearly_price),
|
||||
trial_days: parseFloat(formState.trial_days)
|
||||
monthly_price: currencyFromDecimal(parseFloat(formState.monthly_price)),
|
||||
yearly_price: currencyFromDecimal(parseFloat(formState.yearly_price)),
|
||||
trial_days: currencyFromDecimal(parseFloat(formState.trial_days))
|
||||
};
|
||||
|
||||
if (tier?.id) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Button from '../../../../admin-x-ds/global/Button';
|
||||
import Icon from '../../../../admin-x-ds/global/Icon';
|
||||
import React from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import {Tier} from '../../../../types/api';
|
||||
import {getNonDecimal, getSymbol} from '../../../../utils/currency';
|
||||
import {getSymbol} from '../../../../utils/currency';
|
||||
|
||||
export type TierFormState = Partial<Omit<Tier, 'monthly_price' | 'yearly_price' | 'trial_days'>> & {
|
||||
monthly_price: string;
|
||||
|
@ -57,19 +58,28 @@ const DiscountLabel: React.FC<{discount: number}> = ({discount}) => {
|
|||
};
|
||||
|
||||
const TierDetailPreview: React.FC<TierDetailPreviewProps> = ({tier}) => {
|
||||
const [showingYearly, setShowingYearly] = useState(false);
|
||||
|
||||
const name = tier?.name || '';
|
||||
const description = tier?.description || '';
|
||||
const monthlyPrice = getNonDecimal(parseFloat(tier?.monthly_price || '0'));
|
||||
const trialDays = parseFloat(tier?.trial_days || '0');
|
||||
const currency = tier?.currency || 'USD';
|
||||
const currencySymbol = currency ? getSymbol(currency) : '$';
|
||||
const benefits = tier?.benefits || [];
|
||||
|
||||
const monthlyPrice = parseFloat(tier?.monthly_price || '0');
|
||||
const yearlyPrice = parseFloat(tier?.yearly_price || '0');
|
||||
const yearlyDiscount = tier?.monthly_price && tier?.yearly_price
|
||||
? Math.ceil(((monthlyPrice * 12 - yearlyPrice) / (monthlyPrice * 12)) * 100)
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<div className="-mt-[6px]">
|
||||
<div className="flex items-baseline justify-between">
|
||||
<h4 className="z-10 pb-3 text-2xs font-semibold uppercase tracking-wide text-grey-700">Tier preview</h4>
|
||||
<div>
|
||||
<div className="flex">
|
||||
<Button label="Monthly" onClick={() => setShowingYearly(false)} />
|
||||
<Button label="Yearly" onClick={() => setShowingYearly(true)} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-column relative flex min-h-[200px] w-full max-w-[420px] items-start justify-stretch rounded border border-grey-200 bg-white p-8">
|
||||
|
@ -78,12 +88,12 @@ const TierDetailPreview: React.FC<TierDetailPreviewProps> = ({tier}) => {
|
|||
<div className="mt-4 flex w-full flex-row flex-wrap items-end justify-between gap-x-1 gap-y-[10px]">
|
||||
<div className="flex flex-wrap text-black">
|
||||
<span className="self-start text-[2.7rem] font-bold uppercase leading-[1.115]">{currencySymbol}</span>
|
||||
<span className="break-all text-[3.4rem] font-bold leading-none tracking-tight">{monthlyPrice}</span>
|
||||
<span className="ml-1 self-end text-[1.5rem] leading-snug text-grey-800">/month</span>
|
||||
<span className="break-all text-[3.4rem] font-bold leading-none tracking-tight">{showingYearly ? yearlyPrice : monthlyPrice}</span>
|
||||
<span className="ml-1 self-end text-[1.5rem] leading-snug text-grey-800">/{showingYearly ? 'year' : 'month'}</span>
|
||||
</div>
|
||||
<TrialDaysLabel trialDays={trialDays} />
|
||||
</div>
|
||||
<DiscountLabel discount={25} />
|
||||
{(showingYearly && yearlyDiscount > 0) && <DiscountLabel discount={yearlyDiscount} />}
|
||||
</div>
|
||||
<div className="flex-column flex w-full flex-1">
|
||||
<div className="flex-1">
|
||||
|
@ -96,4 +106,4 @@ const TierDetailPreview: React.FC<TierDetailPreviewProps> = ({tier}) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default TierDetailPreview;
|
||||
export default TierDetailPreview;
|
||||
|
|
|
@ -133,6 +133,10 @@ export function getSymbol(currency: string): string {
|
|||
}
|
||||
|
||||
// We currently only support decimal currencies
|
||||
export function getNonDecimal(amount: number): number {
|
||||
return amount / 100;
|
||||
}
|
||||
export function currencyToDecimal(integerAmount: number): number {
|
||||
return integerAmount / 100;
|
||||
}
|
||||
|
||||
export function currencyFromDecimal(decimalAmount: number): number {
|
||||
return decimalAmount * 100;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue