Show Add offer button on settings screen if no offer is present (#19215)

Ref
[PROD-3](https://linear.app/tryghost/issue/PROD-3/settings-group-navigation-handling)
This commit is contained in:
Princi Vershwal 2023-12-06 10:01:48 +05:30 committed by GitHub
parent 9eed858e8e
commit 5a4d98e90d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 12 deletions

View File

@ -48,17 +48,21 @@ const Offers: React.FC<{ keywords: string[] }> = ({keywords}) => {
const latestThree = activeOffers.slice(0, 3); const latestThree = activeOffers.slice(0, 3);
const openModal = () => { const openOfferListModal = () => {
updateRoute('offers/edit'); updateRoute('offers/edit');
}; };
const openAddModal = () => {
updateRoute('offers/new');
};
const goToOfferEdit = (offerId: string) => { const goToOfferEdit = (offerId: string) => {
updateRoute(`offers/edit/${offerId}`); updateRoute(`offers/edit/${offerId}`);
}; };
return ( return (
<TopLevelGroup <TopLevelGroup
customButtons={<Button color='green' disabled={!checkStripeEnabled(settings, config)} label='Manage offers' link linkWithPadding onClick={openModal}/>} customButtons={<Button color='green' disabled={!checkStripeEnabled(settings, config)} label={allOffers.length > 0 ? 'Manage offers' : 'Add offers'} link linkWithPadding onClick={allOffers.length > 0 ? openOfferListModal : openAddModal}/>}
description={<>Create discounts & coupons to boost new subscriptions. {allOffers.length === 0 && <a className='text-green' href="https://ghost.org/help/offers" rel="noopener noreferrer" target="_blank">Learn more</a>}</>} description={<>Create discounts & coupons to boost new subscriptions. {allOffers.length === 0 && <a className='text-green' href="https://ghost.org/help/offers" rel="noopener noreferrer" target="_blank">Learn more</a>}</>}
keywords={keywords} keywords={keywords}
navid='offers' navid='offers'

View File

@ -14,16 +14,16 @@ test.describe('Offers Modal', () => {
}}); }});
await page.goto('/'); await page.goto('/');
const section = page.getByTestId('offers'); const section = page.getByTestId('offers');
await section.getByRole('button', {name: 'Manage offers'}).click(); await section.getByRole('button', {name: 'Add offers'}).click();
const modal = page.getByTestId('offers-modal'); const addModal = page.getByTestId('add-offer-modal');
await expect(modal).toBeVisible(); await expect(addModal).toBeVisible();
}); });
test('Offers Add Modal is available', async ({page}) => { test('Offers Add Modal is available', async ({page}) => {
await mockApi({page, requests: { await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}, browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
addOffer: {method: 'POST', path: '/offers/', response: { addOffer: {method: 'POST', path: '/offers/', response: {
offers: [{ offers: [{
@ -45,9 +45,9 @@ test.describe('Offers Modal', () => {
test('Can add a new offer', async ({page}) => { test('Can add a new offer', async ({page}) => {
const {lastApiRequests} = await mockApi({page, requests: { const {lastApiRequests} = await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers}, browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}, browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
addOffer: {method: 'POST', path: `/offers/`, response: { addOffer: {method: 'POST', path: `/offers/`, response: {
@ -85,9 +85,9 @@ test.describe('Offers Modal', () => {
test('Errors if required fields are missing', async ({page}) => { test('Errors if required fields are missing', async ({page}) => {
await mockApi({page, requests: { await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers}, browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}, browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
addOffer: {method: 'POST', path: `/offers/`, response: { addOffer: {method: 'POST', path: `/offers/`, response: {
@ -112,9 +112,9 @@ test.describe('Offers Modal', () => {
test('Shows validation hints', async ({page}) => { test('Shows validation hints', async ({page}) => {
await mockApi({page, requests: { await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers}, browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}, browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
addOffer: {method: 'POST', path: `/offers/`, response: { addOffer: {method: 'POST', path: `/offers/`, response: {
@ -144,9 +144,10 @@ test.describe('Offers Modal', () => {
test('Can view active offers', async ({page}) => { test('Can view active offers', async ({page}) => {
await mockApi({page, requests: { await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers}, browseAllOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers} browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}
}}); }});
@ -161,9 +162,10 @@ test.describe('Offers Modal', () => {
test('Can view archived offers', async ({page}) => { test('Can view archived offers', async ({page}) => {
await mockApi({page, requests: { await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers}, browseAllOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers} browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}
}}); }});
@ -178,9 +180,10 @@ test.describe('Offers Modal', () => {
test('Supports updating an offer', async ({page}) => { test('Supports updating an offer', async ({page}) => {
const {lastApiRequests} = await mockApi({page, requests: { const {lastApiRequests} = await mockApi({page, requests: {
browseOffers: {method: 'GET', path: '/offers/', response: responseFixtures.offers},
...globalDataRequests, ...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe}, browseSettings: {...globalDataRequests.browseSettings, response: settingsWithStripe},
browseOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers}, browseAllOffers: {method: 'GET', path: '/offers/?limit=all', response: responseFixtures.offers},
browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers}, browseOffersById: {method: 'GET', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: responseFixtures.offers},
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}, browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
editOffer: {method: 'PUT', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: { editOffer: {method: 'PUT', path: `/offers/${responseFixtures.offers.offers![0].id}/`, response: {