From fb3eb3ac5c0178d9850f9ef25c960e967391e6bc Mon Sep 17 00:00:00 2001 From: Ronald Langeveld Date: Wed, 15 Nov 2023 14:52:32 +0700 Subject: [PATCH] Added Portal Preview to Edit Page - Offers X (#18985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs https://github.com/TryGhost/Product/issues/4150 --- ### 🤖 Generated by Copilot at bced508 This pull request improves the offer modal UI and functionality by using consistent values for discount amount types, adding a portal preview feature, and fixing some bugs and syntax errors in the code. The changes affect the files `AddOfferModal.tsx`, `EditOfferModal.tsx`, and `getOffersPortalPreviewUrl.ts`. --- .../settings/growth/offers/AddOfferModal.tsx | 12 ++-- .../settings/growth/offers/EditOfferModal.tsx | 59 ++++++++++++++++++- .../src/utils/getOffersPortalPreviewUrl.ts | 8 +-- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/apps/admin-x-settings/src/components/settings/growth/offers/AddOfferModal.tsx b/apps/admin-x-settings/src/components/settings/growth/offers/AddOfferModal.tsx index 2a7e54cf02..b758d46246 100644 --- a/apps/admin-x-settings/src/components/settings/growth/offers/AddOfferModal.tsx +++ b/apps/admin-x-settings/src/components/settings/growth/offers/AddOfferModal.tsx @@ -116,7 +116,7 @@ const Sidebar: React.FC = ({tierOptions, clearBg={true} controlClasses={{menu: 'w-20 right-0'}} options={amountOptions} - selectedOption={overrides.amountType === 'percentageOff' ? amountOptions[0] : amountOptions[1]} + selectedOption={overrides.amountType === 'percent' ? amountOptions[0] : amountOptions[1]} onSelect={(e) => { handleAmountTypeChange(e?.value || ''); }} @@ -218,10 +218,10 @@ const AddOfferModal = () => { } }); const getDiscountAmount = (discount: number, dctype: string) => { - if (dctype === 'percentageOff') { + if (dctype === 'percent') { return discount.toString(); } - if (dctype === 'currencyOff') { + if (dctype === 'fixed') { let calcDiscount = discount * 100; return calcDiscount.toString(); } @@ -249,7 +249,7 @@ const AddOfferModal = () => { currency: selectedTier?.dataset?.currency || '', status: 'active', tierId: selectedTier?.dataset?.id || '', - amountType: 'percentageOff' + amountType: 'percent' }, onSave: async () => { const dataset = { @@ -285,8 +285,8 @@ const AddOfferModal = () => { }); const amountOptions = [ - {value: 'percentageOff', label: '%'}, - {value: 'currencyOff', label: formState.currency} + {value: 'percent', label: '%'}, + {value: 'fixed', label: formState.currency} ]; const handleTierChange = (tier: SelectOption) => { diff --git a/apps/admin-x-settings/src/components/settings/growth/offers/EditOfferModal.tsx b/apps/admin-x-settings/src/components/settings/growth/offers/EditOfferModal.tsx index 14b01ce9f1..4051386087 100644 --- a/apps/admin-x-settings/src/components/settings/growth/offers/EditOfferModal.tsx +++ b/apps/admin-x-settings/src/components/settings/growth/offers/EditOfferModal.tsx @@ -1,10 +1,12 @@ import NiceModal, {useModal} from '@ebay/nice-modal-react'; +import PortalFrame from '../../membership/portal/PortalFrame'; import useFeatureFlag from '../../../../hooks/useFeatureFlag'; import useForm, {ErrorMessages} from '../../../../hooks/useForm'; import {Button, ConfirmationModal, Form, PreviewModalContent, TextArea, TextField, showToast} from '@tryghost/admin-x-design-system'; import {Offer, useBrowseOffersById, useEditOffer} from '@tryghost/admin-x-framework/api/offers'; import {RoutingModalProps, useRouting} from '@tryghost/admin-x-framework/routing'; import {getHomepageUrl} from '@tryghost/admin-x-framework/api/site'; +import {getOfferPortalPreviewUrl, offerPortalPreviewUrlTypes} from '../../../../utils/getOffersPortalPreviewUrl'; import {useEffect, useState} from 'react'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; import {useHandleError} from '@tryghost/admin-x-framework/hooks'; @@ -137,12 +139,15 @@ const Sidebar: React.FC<{ }; const EditOfferModal: React.FC = ({params}) => { + const {siteData} = useGlobalData(); const modal = useModal(); const {updateRoute} = useRouting(); const handleError = useHandleError(); const hasOffers = useFeatureFlag('adminXOffers'); const {mutateAsync: editOffer} = useEditOffer(); + const [href, setHref] = useState(''); + useEffect(() => { if (!hasOffers) { modal.remove(); @@ -176,7 +181,7 @@ const EditOfferModal: React.FC = ({params}) => { useEffect(() => { setFormState(() => offerById[0]); - }, [setFormState, offerById[0]]); + }, [setFormState, offerById]); const updateOffer = (fields: Partial) => { updateForm(state => ({...state, ...fields})); @@ -190,10 +195,62 @@ const EditOfferModal: React.FC = ({params}) => { validate={validate} />; + // { + // "id": "65541d87ac4bfaf85f35e773", + // "name": "apples", + // "code": "apples", + // "display_title": "apples", + // "display_description": "A new appple", + // "type": "percent", + // "cadence": "month", + // "amount": 30, + // "duration": "forever", + // "duration_in_months": null, + // "currency_restriction": false, + // "currency": null, + // "status": "active", + // "redemption_count": 0, + // "tier": { + // "id": "6535e75005fd81e1492d0cca", + // "name": "Ronald SQLite Dev" + // } + // } + + useEffect(() => { + const dataset : offerPortalPreviewUrlTypes = { + name: formState?.name || '', + code: { + value: formState?.code || '' + }, + displayTitle: { + value: formState?.display_title || '' + }, + displayDescription: formState?.display_description || '', + type: formState?.type || '', + cadence: formState?.cadence || '', + trialAmount: formState?.amount, + discountAmount: formState?.amount, + duration: formState?.duration || '', + durationInMonths: formState?.duration_in_months || 0, + currency: formState?.currency || '', + status: formState?.status || '', + tierId: formState?.tier.id || '', + amountType: formState?.type === 'percent' ? 'percent' : 'amount' + }; + + const newHref = getOfferPortalPreviewUrl(dataset, siteData.url); + setHref(newHref); + }, [formState, siteData]); + + const iframe = ; + return offerById ? { - if (dctype === 'percentageOff') { + if (dctype === 'percent') { return discount.toString(); } - if (dctype === 'currencyOff') { + if (dctype === 'fixed') { settingsParam.append('type', encodeURIComponent('fixed')); let calcDiscount = discount * 100; return calcDiscount.toString(); } }; - + settingsParam.append('name', encodeURIComponent(name)); settingsParam.append('code', encodeURIComponent(code.value)); settingsParam.append('display_title', encodeURIComponent(displayTitle.value)); @@ -74,7 +74,7 @@ export const getOfferPortalPreviewUrl = (overrides:offerPortalPreviewUrlTypes, b settingsParam.append('currency', encodeURIComponent(currency)); settingsParam.append('status', encodeURIComponent(status)); settingsParam.append('tier_id', encodeURIComponent(tierId)); - settingsParam.append('amount', encodeURIComponent(type === 'trial' ? trialAmount.toString() : getDiscountAmount(discountAmount, amountType ? amountType : 'currencyOff') || '0')); + settingsParam.append('amount', encodeURIComponent(type === 'trial' ? trialAmount.toString() : getDiscountAmount(discountAmount, amountType ? amountType : 'fixed') || '0')); if (disableBackground) { settingsParam.append('disableBackground', 'true');