Skip to content

Commit

Permalink
Merge pull request #723 from Financial-Times/ENTST-538-update-footer-…
Browse files Browse the repository at this point in the history
…copy-for-free-articles

ENTST-538: update copy for free article
  • Loading branch information
abshirahmed authored Jul 6, 2023
2 parents b5aa632 + 531fe9a commit f271cf2
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 39 deletions.
15 changes: 15 additions & 0 deletions components/x-gift-article/__tests__/x-gift-article.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,19 @@ describe('x-gift-article', () => {

expect(subject.find('#social-share-buttons')).toExist()
})

it('should display the free article message when isFreeArticle is true', async () => {
const args = {
...baseArgs,
isFreeArticle: true
}
const subject = mount(<ShareArticleModal {...args} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()

subject.update()

expect(subject.find('#free-article-alert')).toExist()
expect(subject.find('#share-with-non-subscribers-checkbox')).not.toExist()
})
})
19 changes: 13 additions & 6 deletions components/x-gift-article/src/GiftArticle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ const withGiftFormActions = withActions(

async shortenNonGiftUrl() {
return async (state) => {
if (state.isNonGiftUrlShortened) {
state.showFreeArticleAlert = false
return state
}
const { url, isShortened } = await api.getShorterUrl(state.urls.nonGift)
tracking.createNonGiftLink(url, state.urls.nonGift)

Expand Down Expand Up @@ -172,15 +176,17 @@ const withGiftFormActions = withActions(

if (initialProps.isFreeArticle) {
const { url, isShortened } = await api.getShorterUrl(state.urls.nonGift)

if (isShortened) {
updaters.setShortenedNonGiftUrl(url)(state)
}
return {
const freeArticleState = {
invalidResponseFromApi: true,
enterpriseEnabled: enabled,
...enterpriseState
}

if (isShortened) {
Object.assign(freeArticleState, updaters.setShortenedNonGiftUrl(url)(state))
freeArticleState.showFreeArticleAlert = true
}
return freeArticleState
} else {
const { giftCredits, monthlyAllowance, nextRenewalDate } = await api.getGiftArticleAllowance()

Expand Down Expand Up @@ -286,7 +292,8 @@ const withGiftFormActions = withActions(
whatsapp: `whatsapp://send?text=${encodeURIComponent(props.article.title)}%20-%20${encodeURIComponent(
props.article.url
)}`
}
},
showFreeArticleAlert: false
}

const expandedProps = Object.assign({}, props, initialState)
Expand Down
31 changes: 31 additions & 0 deletions components/x-gift-article/src/v2/CreateLinkButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from '../lib/constants'

export const CreateLinkButton = ({ shareType, actions, enterpriseEnabled }) => {
const createLinkHandler = async () => {
switch (shareType) {
case ShareType.gift:
await actions.createGiftUrl()
break
case ShareType.nonGift:
await actions.shortenNonGiftUrl()
break
case ShareType.enterprise:
await actions.createEnterpriseUrl()
break
default:
}
actions.initOShare('#social-share-buttons')
}
return (
<button
id="create-link-button"
className={`o-buttons o-buttons--big o-buttons--primary share-article-dialog__create-link-button ${
enterpriseEnabled ? 'o-buttons--professional' : ''
}`}
onClick={createLinkHandler}
>
Create link
</button>
)
}
17 changes: 14 additions & 3 deletions components/x-gift-article/src/v2/FooterMessage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export const FooterMessage = ({
isNonGiftUrlShortened,
enterpriseEnabled,
enterpriseRequestAccess,
includeHighlights
includeHighlights,
isFreeArticle,
showFreeArticleAlert
}) => {
// if the share link has not been created
// if the share link button has not been clicked yet
if (!isGiftUrlCreated && !isNonGiftUrlShortened) {
// when the user is b2b and has advanced sharing enabled
if (enterpriseEnabled && !enterpriseRequestAccess) {
Expand All @@ -24,11 +26,12 @@ export const FooterMessage = ({
target="_blank"
rel="noreferrer"
>
Tell me more about Enterprise Sharing
Tell me more about Advanced Sharing
</a>
</div>
)
}

return enterpriseEnabled ? ( // when the user is b2b
<p className="share-article-dialog__footer-message">
Send to multiple people with{' '}
Expand All @@ -46,6 +49,14 @@ export const FooterMessage = ({

// when the share link has been created

if (isFreeArticle) {
return !showFreeArticleAlert ? (
<p className="share-article-dialog__footer-message-shared-link">
Anyone will be able to see the full article using this link.
</p>
) : null
}

if (shareType === ShareType.gift) {
const redemptionLimitUnit = redemptionLimit === 1 ? 'time' : 'times'
const creditUnit = giftCredits === 1 ? 'credit' : 'credits'
Expand Down
21 changes: 21 additions & 0 deletions components/x-gift-article/src/v2/FreeArticleAlert.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { h } from '@financial-times/x-engine'

export const FreeArticleAlert = () => {
return (
<div
id="free-article-alert"
className="o-message o-message--alert o-message--received-highlights share-article-dialog__alert"
data-o-component="o-message"
>
<div className="o-message__container">
<div className="o-message__content">
<p className="o-message__content-main">
<strong>This is one of our free articles</strong>
<br />
Even non-subscribers can read it, without using up your sharing credits.
</p>
</div>
</div>
</div>
)
}
38 changes: 10 additions & 28 deletions components/x-gift-article/src/v2/GiftLinkSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,25 @@ import { h } from '@financial-times/x-engine'
import { SharedLinkTypeSelector } from './SharedLinkTypeSelector'
import { ShareType } from '../lib/constants'
import { UrlSection } from './UrlSection'
import { CreateLinkButton } from './CreateLinkButton'
import { FreeArticleAlert } from './FreeArticleAlert'

export const GiftLinkSection = (props) => {
const { isGiftUrlCreated, actions, shareType, isNonGiftUrlShortened, enterpriseEnabled } = props

const createLinkHandler = async () => {
switch (shareType) {
case ShareType.gift:
await actions.createGiftUrl()
break
case ShareType.nonGift:
await actions.shortenNonGiftUrl()
break
case ShareType.enterprise:
await actions.createEnterpriseUrl()
break
default:
}
actions.initOShare('#social-share-buttons')
}
const { isGiftUrlCreated, shareType, isNonGiftUrlShortened, showFreeArticleAlert } = props

// when the gift url is created or the non-gift url is shortened, show the url section
if (isGiftUrlCreated || (shareType === ShareType.nonGift && isNonGiftUrlShortened)) {
if (
isGiftUrlCreated ||
(shareType === ShareType.nonGift && isNonGiftUrlShortened && !showFreeArticleAlert)
) {
return <UrlSection {...props} />
}

return (
<div>
<SharedLinkTypeSelector {...props} />
<button
id="create-link-button"
className={`o-buttons o-buttons--big o-buttons--primary share-article-dialog__create-link-button ${
enterpriseEnabled ? 'o-buttons--professional' : ''
}`}
onClick={createLinkHandler}
>
Create link
</button>
{showFreeArticleAlert && <FreeArticleAlert />}
{!showFreeArticleAlert && <SharedLinkTypeSelector {...props} />}
<CreateLinkButton {...props} />
</div>
)
}
14 changes: 12 additions & 2 deletions components/x-gift-article/src/v2/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from '../lib/constants'

export const Header = ({ title, article, isGiftUrlCreated, shareType, isNonGiftUrlShortened }) => {
export const Header = ({
title,
article,
isGiftUrlCreated,
shareType,
isNonGiftUrlShortened,
showFreeArticleAlert
}) => {
// when a gift link is created or shortened, the title is "Sharing link"
if (isGiftUrlCreated || (shareType === ShareType.nonGift && isNonGiftUrlShortened)) {
if (
isGiftUrlCreated ||
(shareType === ShareType.nonGift && isNonGiftUrlShortened && !showFreeArticleAlert)
) {
return (
<header>
<div className="share-article-dialog__header-share-link-title">Sharing link</div>
Expand Down
4 changes: 4 additions & 0 deletions components/x-gift-article/src/v2/ShareArticleDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,8 @@

.share-article-dialog__alert {
margin-top: oSpacingByName('s4');
margin-bottom: oSpacingByName('s4');
strong {
@include oTypographySans($weight: 'medium');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const SharedLinkTypeSelector = (props) => {

return (
<div
id="share-with-non-subscribers-checkbox"
className={`o-forms-field o-forms-field--optional share-article-dialog__non-subscriber-checkbox ${
enterpriseEnabled ? 'o-forms-field--professional' : ''
}`}
Expand Down
40 changes: 40 additions & 0 deletions components/x-gift-article/storybook/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,43 @@ ShareArticleModalWithAdvancedSharingSaveHighlightsMessage.storyName =
'Share article modal (AS save highlights message)'
ShareArticleModalWithAdvancedSharingSaveHighlightsMessage.args =
require('./share-article-modal-with-advanced-sharing-save-highlights-message').args

export const ShareArticleModalB2BFreeArticle = (args) => {
require('./share-article-modal-b2b-free-article').fetchMock(fetchMock)
return (
<div className="story-container">
{dependencies && <BuildService dependencies={dependencies} />}
<ShareArticleModal {...args} actionsRef={(actions) => actions?.activate()} />
</div>
)
}

ShareArticleModalB2BFreeArticle.storyName = 'Share article modal (B2B free article)'
ShareArticleModalB2BFreeArticle.args = require('./share-article-modal-b2b-free-article').args

export const ShareArticleModalB2CFreeArticle = (args) => {
require('./share-article-modal-b2c-free-article').fetchMock(fetchMock)
return (
<div className="story-container">
{dependencies && <BuildService dependencies={dependencies} />}
<ShareArticleModal {...args} actionsRef={(actions) => actions?.activate()} />
</div>
)
}

ShareArticleModalB2CFreeArticle.storyName = 'Share article modal (B2C free article)'
ShareArticleModalB2CFreeArticle.args = require('./share-article-modal-b2c-free-article').args

export const ShareArticleModalWithAdvancedSharingFreeArticle = (args) => {
require('./share-article-modal-with-advanced-sharing-free-article').fetchMock(fetchMock)
return (
<div className="story-container">
{dependencies && <BuildService dependencies={dependencies} />}
<ShareArticleModal {...args} actionsRef={(actions) => actions?.activate()} />
</div>
)
}

ShareArticleModalWithAdvancedSharingFreeArticle.storyName = 'Share article modal (AS free article)'
ShareArticleModalWithAdvancedSharingFreeArticle.args =
require('./share-article-modal-with-advanced-sharing-free-article').args
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const articleId = 'e4b5ade3-01d1-4db8-b197-257051656684'
const articleUrl = 'https://www.ft.com/content/e4b5ade3-01d1-4db8-b197-257051656684'
const articleUrlRedeemed = 'https://enterprise-sharing.ft.com/gift-url-redeemed'
const nonGiftArticleUrl = `${articleUrl}?shareType=nongift`

exports.args = {
title: 'Share this article:',
isFreeArticle: true,
article: {
id: articleId,
url: articleUrl,
title: 'Equinor and Daimler Truck cut Russia ties as Volvo and JLR halt car deliveries'
},
id: 'base-gift-article-static-id',
enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`
}

exports.fetchMock = (fetchMock) => {
fetchMock
.restore()
.get('path:/article/gift-credits', {
allowance: 20,
consumedCredits: 5,
remainingCredits: 15,
renewalDate: '2018-08-01T00:00:00Z'
})
.get(`path:/article/shorten-url/${encodeURIComponent(articleUrlRedeemed)}`, {
shortenedUrl: 'https://shortened-gift-url'
})
.get(`path:/article/shorten-url/${encodeURIComponent(nonGiftArticleUrl)}`, {
shortenedUrl: 'https://shortened-non-gift-url'
})
.get(`path:/article/gift-link/${encodeURIComponent(articleId)}`, {
redemptionUrl: articleUrlRedeemed,
redemptionLimit: 3,
remainingAllowance: 1
})
.get('path:/v1/users/me/allowance', 403)
.post('path:/v1/shares', {
url: articleUrlRedeemed,
redeemLimit: 120
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const articleId = 'e4b5ade3-01d1-4db8-b197-257051656684'
const articleUrl = 'https://www.ft.com/content/e4b5ade3-01d1-4db8-b197-257051656684'
const articleUrlRedeemed = 'https://enterprise-sharing.ft.com/gift-url-redeemed'
const nonGiftArticleUrl = `${articleUrl}?shareType=nongift`

exports.args = {
title: 'Share this article:',
isFreeArticle: true,
article: {
id: articleId,
url: articleUrl,
title: 'Equinor and Daimler Truck cut Russia ties as Volvo and JLR halt car deliveries'
},
id: 'base-gift-article-static-id',
enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`
}

exports.fetchMock = (fetchMock) => {
fetchMock
.restore()
.get('path:/article/gift-credits', {
allowance: 20,
consumedCredits: 5,
remainingCredits: 15,
renewalDate: '2018-08-01T00:00:00Z'
})
.get(`path:/article/shorten-url/${encodeURIComponent(articleUrlRedeemed)}`, {
shortenedUrl: 'https://shortened-gift-url'
})
.get(`path:/article/shorten-url/${encodeURIComponent(nonGiftArticleUrl)}`, {
shortenedUrl: 'https://shortened-non-gift-url'
})
.get(`path:/article/gift-link/${encodeURIComponent(articleId)}`, {
redemptionUrl: articleUrlRedeemed,
redemptionLimit: 3,
remainingAllowance: 1
})
.get('path:/v1/users/me/allowance', 404)
.post('path:/v1/shares', {
url: articleUrlRedeemed,
redeemLimit: 120
})
}
Loading

0 comments on commit f271cf2

Please sign in to comment.