diff --git a/apps/admin-x-settings/src/api/offers.ts b/apps/admin-x-settings/src/api/offers.ts index 074dcf24d2..51af4b8e3c 100644 --- a/apps/admin-x-settings/src/api/offers.ts +++ b/apps/admin-x-settings/src/api/offers.ts @@ -1,4 +1,5 @@ -import {Meta, createQuery, createQueryWithId} from '../utils/api/hooks'; +import {Meta, createMutation, createQuery, createQueryWithId} from '../utils/api/hooks'; +import {updateQueryCache} from '../utils/api/updateQueries'; export type Offer = { id: string; @@ -26,6 +27,10 @@ export interface OffersResponseType { offers: Offer[] } +export interface OfferEditResponseType extends OffersResponseType { + meta?: Meta +} + const dataType = 'OffersResponseType'; export const useBrowseOffers = createQuery({ @@ -37,3 +42,14 @@ export const useBrowseOffersById = createQueryWithId({ dataType, path: `/offers/` }); + +export const useEditOffer = createMutation({ + method: 'PUT', + path: offer => `/offers/${offer.id}/`, + body: offer => ({offers: [offer]}), + updateQueries: { + dataType, + emberUpdateType: 'createOrUpdate', + update: updateQueryCache('offers') + } +}); diff --git a/apps/admin-x-settings/src/components/settings/membership/offers/EditOfferModal.tsx b/apps/admin-x-settings/src/components/settings/membership/offers/EditOfferModal.tsx index dc3275c5cd..b7c133ce90 100644 --- a/apps/admin-x-settings/src/components/settings/membership/offers/EditOfferModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/offers/EditOfferModal.tsx @@ -1,60 +1,97 @@ import NiceModal, {useModal} from '@ebay/nice-modal-react'; import useFeatureFlag from '../../../../hooks/useFeatureFlag'; +import useForm, {ErrorMessages} from '../../../../hooks/useForm'; +import useHandleError from '../../../../utils/api/handleError'; import useRouting from '../../../../hooks/useRouting'; -import {Button, Form, PreviewModalContent, TextArea, TextField} from '@tryghost/admin-x-design-system'; -import {Offer, useBrowseOffersById} from '../../../../api/offers'; +import {Button, Form, PreviewModalContent, TextArea, TextField, showToast} from '@tryghost/admin-x-design-system'; +import {Offer, useBrowseOffersById, useEditOffer} from '../../../../api/offers'; import {RoutingModalProps} from '../../../providers/RoutingProvider'; -import {useEffect} from 'react'; +import {getHomepageUrl} from '../../../../api/site'; +import {useEffect, useState} from 'react'; +import {useGlobalData} from '../../../providers/GlobalDataProvider'; -const Sidebar: React.FC<{offer: Offer}> = ({offer}) => { - return ( -
-
- -
-

Portal Settings

-
+const Sidebar: React.FC<{ + clearError: (field: string) => void, + errors: ErrorMessages, + offer: Offer, + updateOffer: (fields: Partial) => void, + validate: () => void}> = ({clearError, errors, offer, updateOffer, validate}) => { + const {siteData} = useGlobalData(); + const [isCopied, setIsCopied] = useState(false); + + const offerUrl = `${getHomepageUrl(siteData!)}/#/portal/offers/${offer?.code}`; + const handleCopyClick = async () => { + try { + await navigator.clipboard.writeText(offerUrl); + 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 ( +
+ updateOffer({name: e.target.value})} + onKeyDown={() => clearError('name')} /> - -