Wired up success modal to Admin X (#18987)

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

---

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

This pull request adds a new feature to create and share offers in the
admin-x-settings app. It fixes a bug in the `AddOfferModal` component,
and enhances the `OfferSuccess` component to show and copy the offer
link, and provide social sharing options. It also updates the
`SettingsRouter` component to handle the offer id parameter in the
success route.
This commit is contained in:
Ronald Langeveld 2023-11-15 15:29:01 +07:00 committed by GitHub
parent ab4a21db49
commit ec5b766aaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 8 deletions

View File

@ -33,7 +33,7 @@ export const modalPaths: {[key: string]: ModalName} = {
'embed-signup-form/show': 'EmbedSignupFormModal',
'offers/edit': 'OffersModal',
'offers/new': 'AddOfferModal',
'offers/success': 'OfferSuccess',
'offers/success/:id': 'OfferSuccess',
'offers/:id': 'EditOfferModal',
about: 'AboutModal'
};

View File

@ -260,7 +260,7 @@ const AddOfferModal = () => {
cadence: formState.cadence,
amount: formState.type === 'trial' ? Number(getDiscountAmount(formState.trialAmount, formState.amountType)) : Number(getDiscountAmount(formState.discountAmount, formState.amountType)),
duration: formState.type === 'trial' ? 'trial' : formState.duration,
duration_in_months: formState.durationInMonths,
duration_in_months: Number(formState.durationInMonths),
currency: formState.currency,
status: formState.status,
tier: {
@ -274,7 +274,7 @@ const AddOfferModal = () => {
if (response && response.offers && response.offers.length > 0) {
modal.remove();
updateRoute(`offers/${response.offers[0].id}`);
updateRoute(`offers/success/${response.offers[0].id}`);
}
},
onSaveError: () => {},

View File

@ -1,8 +1,40 @@
import NiceModal from '@ebay/nice-modal-react';
import {Button} from '@tryghost/admin-x-design-system';
import {Modal} from '@tryghost/admin-x-design-system';
import {RoutingModalProps} from '@tryghost/admin-x-framework/routing';
import {getHomepageUrl} from '@tryghost/admin-x-framework/api/site';
import {useBrowseOffersById} from '@tryghost/admin-x-framework/api/offers';
import {useEffect, useState} from 'react';
import {useGlobalData} from '../../../providers/GlobalDataProvider';
const OfferSuccess: React.FC<RoutingModalProps> = ({params}) => {
// const {updateRoute} = useRouting();
const {data: {offers: offerById = []} = {}} = useBrowseOffersById(params?.id ? params?.id : '');
const OfferSuccess = () => {
const [offerLink, setOfferLink] = useState<string>('');
const {siteData} = useGlobalData();
useEffect(() => {
if (offerById.length > 0) {
const offer = offerById[0];
const offerUrl = `${getHomepageUrl(siteData!)}${offer?.code}`;
setOfferLink(offerUrl);
}
}, [offerById, siteData]);
const [isCopied, setIsCopied] = useState(false);
const handleCopyClick = async () => {
try {
await navigator.clipboard.writeText(offerLink);
setIsCopied(true);
setTimeout(() => setIsCopied(false), 1000); // reset after 1 seconds
} catch (err) {
// eslint-disable-next-line no-console
console.error('Failed to copy text: ', err);
}
};
return <Modal
footer={false}
height='full'
@ -13,12 +45,12 @@ const OfferSuccess = () => {
<h1 className='text-4xl'>Your new offer is live!</h1>
<p className='mt-4 max-w-[510px] text-[1.6rem]'>You can share the link anywhere. In your newsletter, social media, a podcast, or in-person. It all just works.</p>
<div className='mt-8 flex w-full max-w-md flex-col gap-8'>
<Button color='green' label='Copy link' fullWidth />
<Button color='green' label={isCopied ? 'Copied!' : 'Copy link'} fullWidth onClick={handleCopyClick} />
<div className='flex items-center gap-4 text-xs font-medium before:h-px before:grow before:bg-grey-300 before:content-[""] after:h-px after:grow after:bg-grey-300 after:content-[""]'>OR</div>
<div className='flex gap-2'>
<Button className='h-8 border border-grey-300' icon='twitter-x' iconColorClass='w-[14px] h-[14px]' size='sm' fullWidth />
<Button className='h-8 border border-grey-300' icon='facebook' size='sm' fullWidth />
<Button className='h-8 border border-grey-300' icon='linkedin' size='sm' fullWidth />
<Button className='h-8 border border-grey-300' disabled={true} icon='twitter-x' iconColorClass='w-[14px] h-[14px]' size='sm' fullWidth />
<Button className='h-8 border border-grey-300' disabled={true} icon='facebook' size='sm' fullWidth />
<Button className='h-8 border border-grey-300' disabled={true} icon='linkedin' size='sm' fullWidth />
</div>
</div>
</div>