Added Portal Preview to Edit Page - Offers X (#18985)

refs https://github.com/TryGhost/Product/issues/4150

---

<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at bced508</samp>

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`.
This commit is contained in:
Ronald Langeveld 2023-11-15 14:52:32 +07:00 committed by GitHub
parent a083ce35b9
commit fb3eb3ac5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 11 deletions

View File

@ -116,7 +116,7 @@ const Sidebar: React.FC<SidebarProps> = ({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) => {

View File

@ -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<RoutingModalProps> = ({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<string>('');
useEffect(() => {
if (!hasOffers) {
modal.remove();
@ -176,7 +181,7 @@ const EditOfferModal: React.FC<RoutingModalProps> = ({params}) => {
useEffect(() => {
setFormState(() => offerById[0]);
}, [setFormState, offerById[0]]);
}, [setFormState, offerById]);
const updateOffer = (fields: Partial<Offer>) => {
updateForm(state => ({...state, ...fields}));
@ -190,10 +195,62 @@ const EditOfferModal: React.FC<RoutingModalProps> = ({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 = <PortalFrame
href={href}
/>;
return offerById ? <PreviewModalContent deviceSelector={false}
dirty={saveState === 'unsaved'}
okColor={okProps.color}
okLabel={okProps.label || 'Save'}
preview={iframe}
sidebar={sidebar}
size='full'
testId='offer-update-modal'

View File

@ -54,16 +54,16 @@ export const getOfferPortalPreviewUrl = (overrides:offerPortalPreviewUrlTypes, b
settingsParam.append('type', encodeURIComponent(type));
const getDiscountAmount = (discount: number, dctype: string) => {
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');