From 4424f2597060057122ae0dd5411ba935cbdbf080 Mon Sep 17 00:00:00 2001 From: Rishabh Garg Date: Wed, 12 Jul 2023 18:56:28 +0530 Subject: [PATCH] Wired data to tier preview in adminX (#17323) refs https://github.com/TryGhost/Product/issues/3580 --- .../membership/tiers/TierDetailModal.tsx | 11 +- .../membership/tiers/TierDetailPreview.tsx | 95 +++++++++--- apps/admin-x-settings/src/utils/currency.ts | 138 ++++++++++++++++++ 3 files changed, 218 insertions(+), 26 deletions(-) create mode 100644 apps/admin-x-settings/src/utils/currency.ts diff --git a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx index c1e9cac23a..513f0aeba0 100644 --- a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx @@ -18,11 +18,18 @@ interface TierDetailModalProps { tier?: Tier } +type TierFormState = Partial> & { + monthly_price: string; + yearly_price: string; + trial_days: string; +}; + const TierDetailModal: React.FC = ({tier}) => { const modal = useModal(); const {updateRoute} = useRouting(); const {update: updateTier, create: createTier} = useTiers(); - const {formState, updateForm, handleSave} = useForm({ + + const {formState, updateForm, handleSave} = useForm({ initialState: { ...(tier || {}), monthly_price: tier?.monthly_price?.toString() || '', @@ -135,7 +142,7 @@ const TierDetailModal: React.FC = ({tier}) => {
- +
; diff --git a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx index c9cde36545..2dd0e2a961 100644 --- a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx @@ -1,9 +1,70 @@ import Icon from '../../../../admin-x-ds/global/Icon'; import React from 'react'; +import {Tier} from '../../../../types/api'; +import {getNonDecimal, getSymbol} from '../../../../utils/currency'; -interface TierDetailPreviewProps {} +export type TierFormState = Partial> & { + monthly_price: string; + yearly_price: string; + trial_days: string; +}; + +interface TierDetailPreviewProps { + tier: TierFormState +} + +const TrialDaysLabel: React.FC<{trialDays: number}> = ({trialDays}) => { + if (!trialDays) { + return null; + } + return ( + + + {trialDays} days free + + ); +}; + +const TierBenefits: React.FC<{benefits: string[]}> = ({benefits}) => { + if (!benefits?.length) { + return null; + } + return ( + <> + { + benefits.map((benefit) => { + return ( +
+
+ +
{benefit}
+
+
+ ); + }) + } + + ); +}; + +const DiscountLabel: React.FC<{discount: number}> = ({discount}) => { + if (!discount) { + return null; + } + return ( + {discount}% discount + ); +}; + +const TierDetailPreview: React.FC = ({tier}) => { + 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 TierDetailPreview: React.FC = () => { return (
@@ -13,35 +74,21 @@ const TierDetailPreview: React.FC = () => {
-

Bronze

+

{name}

- $ - 42 - /year + {currencySymbol} + {monthlyPrice} + /month
- - - 7 days free - +
- 25% discount +
-
Full access to premium content
-
-
- -
Blogs that you can watch and listen to on your favorite podcast apps
-
-
-
-
- -
Blogs that you can watch and listen to on your favorite podcast apps
-
-
+
{description}
+
diff --git a/apps/admin-x-settings/src/utils/currency.ts b/apps/admin-x-settings/src/utils/currency.ts new file mode 100644 index 0000000000..4098e1e85e --- /dev/null +++ b/apps/admin-x-settings/src/utils/currency.ts @@ -0,0 +1,138 @@ +type CurrencyOption = { + isoCode: string; + name: string; +}; + +export const currencies: CurrencyOption[] = [ + {isoCode: 'USD', name: 'United States dollar'}, + {isoCode: 'EUR', name: 'Euro'}, + {isoCode: 'GBP', name: 'Pound sterling'}, + {isoCode: 'AUD', name: 'Australian dollar'}, + {isoCode: 'CAD', name: 'Canadian dollar'}, + {isoCode: 'AED', name: 'United Arab Emirates dirham'}, + {isoCode: 'AFN', name: 'Afghan afghani'}, + {isoCode: 'ALL', name: 'Albanian lek'}, + {isoCode: 'AMD', name: 'Armenian dram'}, + {isoCode: 'ANG', name: 'Netherlands Antillean guilder'}, + {isoCode: 'AOA', name: 'Angolan kwanza'}, + {isoCode: 'ARS', name: 'Argentine peso'}, + {isoCode: 'AWG', name: 'Aruban florin'}, + {isoCode: 'AZN', name: 'Azerbaijani manat'}, + {isoCode: 'BAM', name: 'Bosnia and Herzegovina convertible mark'}, + {isoCode: 'BBD', name: 'Barbados dollar'}, + {isoCode: 'BDT', name: 'Bangladeshi taka'}, + {isoCode: 'BGN', name: 'Bulgarian lev'}, + {isoCode: 'BMD', name: 'Bermudian dollar'}, + {isoCode: 'BND', name: 'Brunei dollar'}, + {isoCode: 'BOB', name: 'Boliviano'}, + {isoCode: 'BRL', name: 'Brazilian real'}, + {isoCode: 'BSD', name: 'Bahamian dollar'}, + {isoCode: 'BWP', name: 'Botswana pula'}, + {isoCode: 'BZD', name: 'Belize dollar'}, + {isoCode: 'CDF', name: 'Congolese franc'}, + {isoCode: 'CHF', name: 'Swiss franc'}, + {isoCode: 'CNY', name: 'Chinese yuan'}, + {isoCode: 'COP', name: 'Colombian peso'}, + {isoCode: 'CRC', name: 'Costa Rican colon'}, + {isoCode: 'CVE', name: 'Cape Verdean escudo'}, + {isoCode: 'CZK', name: 'Czech koruna'}, + {isoCode: 'DKK', name: 'Danish krone'}, + {isoCode: 'DOP', name: 'Dominican peso'}, + {isoCode: 'DZD', name: 'Algerian dinar'}, + {isoCode: 'EGP', name: 'Egyptian pound'}, + {isoCode: 'ETB', name: 'Ethiopian birr'}, + {isoCode: 'FJD', name: 'Fiji dollar'}, + {isoCode: 'FKP', name: 'Falkland Islands pound'}, + {isoCode: 'GEL', name: 'Georgian lari'}, + {isoCode: 'GIP', name: 'Gibraltar pound'}, + {isoCode: 'GMD', name: 'Gambian dalasi'}, + {isoCode: 'GTQ', name: 'Guatemalan queztal'}, + {isoCode: 'GYD', name: 'Guyanese dollar'}, + {isoCode: 'HKD', name: 'Hong Kong dollar'}, + {isoCode: 'HNL', name: 'Honduran lempira'}, + {isoCode: 'HRK', name: 'Croation kuna'}, + {isoCode: 'HTG', name: 'Haitian gourde'}, + {isoCode: 'HUF', name: 'Hungarian forint'}, + {isoCode: 'IDR', name: 'Indonesian rupiah'}, + {isoCode: 'ILS', name: 'Israeli new shekel'}, + {isoCode: 'INR', name: 'Indian rupee'}, + {isoCode: 'ISK', name: 'Icelandic króna'}, + {isoCode: 'JMD', name: 'Jamaican dollar'}, + {isoCode: 'KES', name: 'Kenyan shilling'}, + {isoCode: 'KGS', name: 'Kyrgyzstani som'}, + {isoCode: 'KHR', name: 'Cambodian riel'}, + {isoCode: 'KYD', name: 'Cayman Islands dollar'}, + {isoCode: 'KZT', name: 'Kazakhstani tenge'}, + {isoCode: 'LAK', name: 'Lao kip'}, + {isoCode: 'LBP', name: 'Lebanese pound'}, + {isoCode: 'LKR', name: 'Sri Lankan rupee'}, + {isoCode: 'LRD', name: 'Liberian dollar'}, + {isoCode: 'LSL', name: 'Lesotho loti'}, + {isoCode: 'MAD', name: 'Moroccan dirham'}, + {isoCode: 'MDL', name: 'Moldovan leu'}, + {isoCode: 'MKD', name: 'Macedonian denar'}, + {isoCode: 'MMK', name: 'Myanmar kyat'}, + {isoCode: 'MNT', name: 'Mongolian tögrög'}, + {isoCode: 'MOP', name: 'Macanese pataca'}, + {isoCode: 'MRO', name: 'Mauritanian ouguiya'}, + {isoCode: 'MUR', name: 'Mauritian rupee'}, + {isoCode: 'MVR', name: 'Maldivian rufiyaa'}, + {isoCode: 'MWK', name: 'Malawian kwacha'}, + {isoCode: 'MXN', name: 'Mexican peso'}, + {isoCode: 'MYR', name: 'Malaysian ringgit'}, + {isoCode: 'MZN', name: 'Mozambican metical'}, + {isoCode: 'NAD', name: 'Namibian dollar'}, + {isoCode: 'NGN', name: 'Nigerian naira'}, + {isoCode: 'NIO', name: 'Nicaraguan córdoba'}, + {isoCode: 'NOK', name: 'Norwegian krone'}, + {isoCode: 'NPR', name: 'Nepalese rupee'}, + {isoCode: 'NZD', name: 'New Zealand dollar'}, + {isoCode: 'PAB', name: 'Panamanian balboa'}, + {isoCode: 'PEN', name: 'Peruvian sol'}, + {isoCode: 'PGK', name: 'Papua New Guinean kina'}, + {isoCode: 'PHP', name: 'Philippine peso'}, + {isoCode: 'PKR', name: 'Pakistani rupee'}, + {isoCode: 'PLN', name: 'Polish złoty'}, + {isoCode: 'QAR', name: 'Qatari riyal'}, + {isoCode: 'RON', name: 'Romanian leu'}, + {isoCode: 'RSD', name: 'Serbian dinar'}, + {isoCode: 'RUB', name: 'Russian ruble'}, + {isoCode: 'SAR', name: 'Saudi riyal'}, + {isoCode: 'SBD', name: 'Solomon Islands dollar'}, + {isoCode: 'SCR', name: 'Seychelles rupee'}, + {isoCode: 'SEK', name: 'Swedish krona'}, + {isoCode: 'SGD', name: 'Singapore dollar'}, + {isoCode: 'SHP', name: 'Saint Helena pound'}, + {isoCode: 'SLL', name: 'Sierra Leonean leone'}, + {isoCode: 'SOS', name: 'Somali shilling'}, + {isoCode: 'SRD', name: 'Surinamese dollar'}, + {isoCode: 'STD', name: 'São Tomé and Príncipe dobra'}, + {isoCode: 'SZL', name: 'Salvadoran colón'}, + {isoCode: 'THB', name: 'Thai baht'}, + {isoCode: 'TJS', name: 'Tajikistani somoni'}, + {isoCode: 'TOP', name: 'Tongan paʻanga'}, + {isoCode: 'TRY', name: 'Turkish lira'}, + {isoCode: 'TTD', name: 'Trinidad and Tobago dollar'}, + {isoCode: 'TWD', name: 'New Taiwan dollar'}, + {isoCode: 'TZS', name: 'Tanzanian shilling'}, + {isoCode: 'UAH', name: 'Ukrainian hryvnia'}, + {isoCode: 'UYU', name: 'Uruguayan peso'}, + {isoCode: 'UZS', name: 'Uzbekistan som'}, + {isoCode: 'WST', name: 'Samoan tala'}, + {isoCode: 'XCD', name: 'East Caribbean dollar'}, + {isoCode: 'YER', name: 'Yemeni rial'}, + {isoCode: 'ZAR', name: 'South African rand'}, + {isoCode: 'ZMW', name: 'Zambian kwacha'} +]; + +export function getSymbol(currency: string): string { + if (!currency) { + return ''; + } + return Intl.NumberFormat('en', {currency, style: 'currency'}).format(0).replace(/[\d\s.]/g, ''); +} + +// We currently only support decimal currencies +export function getNonDecimal(amount: number): number { + return amount / 100; +} \ No newline at end of file