Skip to content

Commit

Permalink
Merge pull request #709 from Financial-Times/ENTST-425-create-x-dash-…
Browse files Browse the repository at this point in the history
…release-branch

X-Gift article highlights sharing Release
  • Loading branch information
jkerr321 committed Jun 8, 2023
2 parents 4926cfb + 5a3ef66 commit 22f98b2
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 22 deletions.
6 changes: 4 additions & 2 deletions components/x-gift-article/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@financial-times/o-loading": "^5.2.1",
"@financial-times/o-message": "^5.2.1",
"@financial-times/o-normalise": "^3.2.2",
"@financial-times/o-typography": "^7.2.2",
"@financial-times/o-typography": "^7.4.1",
"@financial-times/x-rollup": "file:../../packages/x-rollup",
"check-engine": "^1.10.1",
"sass": "^1.49.0"
Expand All @@ -41,12 +41,14 @@
"extends": "../../package.json"
},
"peerDependencies": {
"@financial-times/o-banner": "^4.4.9",
"@financial-times/o-buttons": "^7.2.2",
"@financial-times/o-colors": "^6.6.0",
"@financial-times/o-forms": "^9.2.3",
"@financial-times/o-labels": "^6.2.2",
"@financial-times/o-loading": "^5.2.1",
"@financial-times/o-message": "^5.2.1",
"@financial-times/o-normalise": "^3.2.2",
"@financial-times/o-typography": "^7.2.2"
"@financial-times/o-typography": "^7.4.1"
}
}
4 changes: 3 additions & 1 deletion components/x-gift-article/src/Buttons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default ({
nativeShare,
actions,
giftCredits,
isFreeArticle
isFreeArticle,
includeHighlights
}) => {
if (isGiftUrlCreated || shareType === ShareType.nonGift) {
if (nativeShare) {
Expand Down Expand Up @@ -80,6 +81,7 @@ export default ({
disabled={!giftCredits}
type="button"
onClick={shareType === ShareType.enterprise ? actions.createEnterpriseUrl : actions.createGiftUrl}
data-trackable={shareType === ShareType.enterprise ? `includeHighlights:${includeHighlights}` : ''}
>
Create {shareType === ShareType.enterprise ? 'enterprise' : 'gift'} link
</button>
Expand Down
15 changes: 14 additions & 1 deletion components/x-gift-article/src/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import UrlSection from './UrlSection'
import MobileShareButtons from './MobileShareButtons'
import CopyConfirmation from './CopyConfirmation'
import { ShareType } from './lib/constants'
import HighlightSection from './HighlightSection'

export default (props) => (
<div className="x-gift-article">
Expand All @@ -25,7 +26,19 @@ export default (props) => (
enterpriseEnabled={props.enterpriseEnabled}
isFreeArticle={props.isFreeArticle}
/>

<HighlightSection
shareType={props.shareType}
hasHighlights={props.hasHighlights}
includeHighlights={props.includeHighlights}
includeHighlightsHandler={props.actions.includeHighlightsHandler}
isGiftUrlCreated={props.isGiftUrlCreated}
saveHighlightsHandler={props.actions.saveHighlightsHandler}
showHighlightsRecipientMessage={props.showHighlightsRecipientMessage}
showHighlightsSuccessMessage={props.showHighlightsSuccessMessage}
showHighlightsCheckbox={props.showHighlightsCheckbox}
closeHighlightsRecipientMessage={props.actions.closeHighlightsRecipientMessage}
closeHighlightsSuccessMessage={props.actions.closeHighlightsSuccessMessage}
/>
<UrlSection {...props} />
</div>
</form>
Expand Down
61 changes: 54 additions & 7 deletions components/x-gift-article/src/GiftArticle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,18 @@ const withGiftFormActions = withActions(
},

async createEnterpriseUrl() {
const { redemptionUrl, redemptionLimit } = await enterpriseApi.getESUrl(initialProps.article.id)

if (redemptionUrl) {
tracking.createESLink(redemptionUrl)
return updaters.setGiftUrl(redemptionUrl, redemptionLimit, false, true)
} else {
return updaters.setErrorState(true)
return async (state) => {
const { redemptionUrl, redemptionLimit } = await enterpriseApi.getESUrl(
initialProps.article.id,
state.includeHighlights
)

if (redemptionUrl) {
tracking.createESLink(redemptionUrl)
return updaters.setGiftUrl(redemptionUrl, redemptionLimit, false, true)(state)
} else {
return updaters.setErrorState(true)
}
}
},

Expand Down Expand Up @@ -188,6 +193,42 @@ const withGiftFormActions = withActions(
}
}
}
},
includeHighlightsHandler() {
return (state) => {
const includeHighlights = !state.includeHighlights
state.includeHighlights = includeHighlights
return { includeHighlights }
}
},
checkIfHasHighlights() {
return (state) => {
state.hasHighlights = !!document.getElementsByClassName(initialProps.highlightClassName).length
return { hasHighlights: state.hasHighlights }
}
},
saveHighlightsHandler() {
return () => {
return {
showHighlightsRecipientMessage: false,
showHighlightsSuccessMessage: true,
showHighlightsCheckbox: true
}
}
},
closeHighlightsRecipientMessage() {
return () => {
return {
showHighlightsRecipientMessage: false
}
}
},
closeHighlightsSuccessMessage() {
return () => {
return {
showHighlightsSuccessMessage: false
}
}
}
}
},
Expand All @@ -202,6 +243,12 @@ const withGiftFormActions = withActions(
isGiftUrlShortened: false,
isNonGiftUrlShortened: false,
isArticleSharingUxUpdates: false,
includeHighlights: false,
hasHighlights: false,
showHighlightsRecipientMessage: new URL(location.href).searchParams.has('highlights'),
showHighlightsSuccessMessage: false,
showHighlightsCheckbox: !new URL(location.href).searchParams.has('highlights'),
highlightClassName: 'user-annotation',
urls: {
dummy: 'https://on.ft.com/gift_link',
gift: undefined,
Expand Down
6 changes: 5 additions & 1 deletion components/x-gift-article/src/GiftArticle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
@import 'Loading.scss';
@import 'Message.scss';
@import 'MobileShareButtons.scss';
@import 'HighlightSection.scss';
@import 'HighlightRecipientMessage.scss';
@import 'HighlightSavedMessage.scss';

.x-gift-article {
@include oTypographySans;
Expand All @@ -28,7 +31,8 @@
$opts: (
'elements': (
'text',
'radio-round'
'radio-round',
'checkbox'
),
'features': (
'inline',
Expand Down
23 changes: 23 additions & 0 deletions components/x-gift-article/src/HighlightCheckbox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { h } from '@financial-times/x-engine'

export default ({ includeHighlightsHandler, includeHighlights, isGiftUrlCreated }) => {
return (
<div className="o-forms-input o-forms-input--checkbox o-forms-field x-gift-article__checkbox">
<label htmlFor="includeHighlights">
<input
type="checkbox"
id="includeHighlights"
name="includeHighlights"
value={includeHighlights}
checked={includeHighlights}
onChange={includeHighlightsHandler}
disabled={isGiftUrlCreated}
data-trackable="make-highlights-visible"
/>
<span className="o-forms-input__label x-gift-article__checkbox-span">
Make highlights visible to recipients
</span>
</label>
</div>
)
}
28 changes: 28 additions & 0 deletions components/x-gift-article/src/HighlightRecipientMessage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { h } from '@financial-times/x-engine'

export default ({ handleSaveAnnotations, handleCloseRecipientMessage }) => {
return (
<div className="x-gift-article-highlight-recipient-message">
<p className="x-gift-article-highlight-recipient-message__title">Share the highlighted article</p>
<div className="x-gift-article-highlight-recipient-message__divider"></div>
<p className="o-typography-professional o-typography-inverse x-gift-article-highlight-recipient-message__description">
If you wish to share the highlighted article,{' '}
<button
type="button"
className="o-typography-link x-gift-article-highlight-recipient-message__save-highlights-button"
onClick={handleSaveAnnotations}
>
save the highlights
</button>{' '}
as your own before creating the link.
</p>
<button
className="x-gift-article-highlight-recipient-message__close"
type="button"
onClick={handleCloseRecipientMessage}
>
<span className="o-normalise-visually-hidden">Close</span>
</button>
</div>
)
}
56 changes: 56 additions & 0 deletions components/x-gift-article/src/HighlightRecipientMessage.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@import '@financial-times/o-colors/main';
@import '@financial-times/o-spacing/main';
@import '@financial-times/o-typography/main';

@include oTypography();

.x-gift-article-highlight-recipient-message {
position: relative;
background-color: oColorsByName('slate');
color: oColorsMix('ft-grey', 'white', 20);
padding: oSpacingByName('s3');

.x-gift-article-highlight-recipient-message__title {
@include oTypographySans($scale: 1, $weight: 'regular');
margin: 0;
color: oColorsByName('white');
}

.x-gift-article-highlight-recipient-message__description {
@include oTypographySans($scale: 0);
margin: 0;
}

.x-gift-article-highlight-recipient-message__divider {
padding-top: oSpacingByName('s2');
padding-bottom: oSpacingByName('s3');
&::after {
border-top: oSpacingByName('s1') solid oColorsByName('mint');
content: '';
position: absolute;
width: 40px;
display: block;
}
}

.x-gift-article-highlight-recipient-message__close {
background-image: url('https://www.ft.com/__origami/service/image/v2/images/raw/fticon-v1%3Across?source=editor&tint=%23FFFFFF&bgcolor=%23FFFFFF');
background-repeat: no-repeat;
background-size: contain;
background-position: 50%;
background-color: transparent;
width: oSpacingByName('s6');
height: oSpacingByName('s6');
border: none;
padding: 0;
position: absolute;
right: oSpacingByName('s2');
top: oSpacingByName('s2');
}

.x-gift-article-highlight-recipient-message__save-highlights-button {
background: none;
border: none;
padding: 0;
}
}
21 changes: 21 additions & 0 deletions components/x-gift-article/src/HighlightSavedMessage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { h } from '@financial-times/x-engine'

export default ({ handleCloseSuccessMessage }) => {
return (
<div
className="o-message o-message--alert o-message--success x-gift-article__highlights-saved-message"
data-o-component="o-message"
>
<div className="o-message__container">
<div className="o-message__content">
<p className="o-message__content-main">
<span className="o-message__content-highlight">Highlights saved.</span>
</p>
<button type="button" className="o-message__close" onClick={handleCloseSuccessMessage}>
<span className="o-normalise-visually-hidden">Close</span>
</button>
</div>
</div>
</div>
)
}
3 changes: 3 additions & 0 deletions components/x-gift-article/src/HighlightSavedMessage.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.x-gift-article__highlights-saved-message {
margin-bottom: oSpacingByName('s4');
}
69 changes: 69 additions & 0 deletions components/x-gift-article/src/HighlightSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { h } from '@financial-times/x-engine'
import { ShareType } from './lib/constants'
import HighlightRecipientMessage from './HighlightRecipientMessage'
import HighlightSavedMessage from './HighlightSavedMessage'
import HighlightCheckbox from './HighlightCheckbox'
import HighlightsApiClient from './lib/highlightsApi'

const USER_ANNOTATIONS_API = `https://enterprise-user-annotations-api.ft.com/v1`

export default ({
shareType,
includeHighlights,
includeHighlightsHandler,
isGiftUrlCreated,
hasHighlights,
saveHighlightsHandler,
showHighlightsRecipientMessage,
showHighlightsSuccessMessage,
showHighlightsCheckbox,
closeHighlightsSuccessMessage,
closeHighlightsRecipientMessage
}) => {
const handleSaveAnnotations = async () => {
const url = new URL(location.href)
const params = new URLSearchParams(url.search)
const highlightsToken = params.get('highlights')
const highlightsAPIClient = new HighlightsApiClient(USER_ANNOTATIONS_API)
const response = await highlightsAPIClient.copySharedHighlights(highlightsToken)

if (response) {
saveHighlightsHandler()
params.delete('highlights')
url.search = params.toString()
localStorage.setItem('showSuccessSavedMessage', 'true')
location.href = url.toString()
}
}

if (shareType === ShareType.enterprise && hasHighlights) {
if (isGiftUrlCreated && includeHighlights) {
return (
<div className="x-gift-article__highlight-section">
<div className="x-gift-article__highlight-shared">highlights visible to recipients</div>
</div>
)
}
return (
<div className="x-gift-article__highlight-section">
{showHighlightsRecipientMessage ? (
<HighlightRecipientMessage
handleSaveAnnotations={handleSaveAnnotations}
handleCloseRecipientMessage={closeHighlightsRecipientMessage}
/>
) : null}
{showHighlightsSuccessMessage ? (
<HighlightSavedMessage handleCloseSuccessMessage={closeHighlightsSuccessMessage} />
) : null}
{showHighlightsCheckbox ? (
<HighlightCheckbox
includeHighlights={includeHighlights}
includeHighlightsHandler={includeHighlightsHandler}
isGiftUrlCreated={isGiftUrlCreated}
/>
) : null}
</div>
)
}
return null
}
Loading

0 comments on commit 22f98b2

Please sign in to comment.