Skip to content

Commit 616a465

Browse files
authored
Merge pull request #14368 from guardian/jm/feat-sign-in-gate-v2
Sign-in gate v2
2 parents 100ec9d + d39df4b commit 616a465

11 files changed

Lines changed: 888 additions & 53 deletions

File tree

dotcom-rendering/fixtures/manual/sign-in-gate.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ export const mockAuxiaResponseDismissible = {
2323
},
2424
};
2525

26+
export const mockAuxiaResponseDismissibleV2 = {
27+
status: true,
28+
data: {
29+
userTreatment: {
30+
treatmentId: 'auxia-treatment-001',
31+
treatmentTrackingId: 'tracking-001',
32+
surface: 'signin-gate',
33+
treatmentContent: JSON.stringify({
34+
title: 'A small step for great Journalism. Sign in.',
35+
subtitle: '',
36+
body: "It's free and only takes 30 seconds.",
37+
first_cta_name: 'Create account',
38+
first_cta_link: 'https://profile.theguardian.com/register',
39+
second_cta_name: "I'll do it later",
40+
}),
41+
},
42+
},
43+
};
44+
2645
export const mockAuxiaResponseNonDismissible = {
2746
status: true,
2847
data: {
@@ -46,6 +65,26 @@ export const mockAuxiaResponseNonDismissible = {
4665
},
4766
};
4867

68+
export const mockAuxiaResponseNonDismissibleV2 = {
69+
status: true,
70+
data: {
71+
userTreatment: {
72+
treatmentId: 'auxia-treatment-002',
73+
treatmentTrackingId: 'tracking-002',
74+
surface: 'signin-gate',
75+
treatmentContent: JSON.stringify({
76+
title: 'Sorry for the interruption. We believe in free, independent journalism for all. Sign in or register to keep reading.',
77+
subtitle:
78+
"Once you are signed in, we'll bring you back here shortly.",
79+
body: '',
80+
first_cta_name: 'Create account',
81+
first_cta_link: 'https://profile.theguardian.com/register',
82+
second_cta_name: '',
83+
}),
84+
},
85+
},
86+
};
87+
4988
export const mockAuxiaResponseLegacy = {
5089
status: true,
5190
data: {
@@ -77,14 +116,25 @@ export const getAuxiaMock = (payload: string): unknown => {
77116
const body = JSON.parse(payload) as Record<string, unknown>;
78117

79118
const mocks = {
80-
dismissable: mockAuxiaResponseDismissible,
81-
'non-dismissable': mockAuxiaResponseNonDismissible,
82-
legacy: mockAuxiaResponseLegacy,
83-
'no-treatment': mockAuxiaResponseNoTreatment,
119+
v1: {
120+
dismissable: mockAuxiaResponseDismissible,
121+
'non-dismissable': mockAuxiaResponseNonDismissible,
122+
legacy: mockAuxiaResponseLegacy,
123+
'no-treatment': mockAuxiaResponseNoTreatment,
124+
},
125+
v2: {
126+
dismissable: mockAuxiaResponseDismissibleV2,
127+
'non-dismissable': mockAuxiaResponseNonDismissibleV2,
128+
legacy: mockAuxiaResponseLegacy,
129+
'no-treatment': mockAuxiaResponseNoTreatment,
130+
},
84131
};
85132

86-
const key = body.sectionId as keyof typeof mocks;
87-
const mock: unknown = mocks[key];
133+
const key = body.sectionId as keyof (typeof mocks)[keyof typeof mocks];
134+
const version = (body.articleIdentifier as string).includes('v2')
135+
? 'v2'
136+
: 'v1';
137+
const mock: unknown = mocks[version][key];
88138

89139
return mock ?? mockAuxiaResponseNoTreatment;
90140
};

dotcom-rendering/src/components/AuthProviderButtons/AuthProviderButtons.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '@guardian/source/react-components';
1414
import React from 'react';
1515
import { buildUrlWithQueryParams } from '../../lib/routeUtils';
16+
import type { AuxiaGateVersion } from '../SignInGate/types';
1617
import type { IsNativeApp, QueryParams } from './types';
1718

1819
type AuthButtonProvider = 'social' | 'email';
@@ -22,6 +23,7 @@ type AuthProviderButtonsProps = {
2223
isNativeApp?: IsNativeApp;
2324
providers: AuthButtonProvider[];
2425
onClick?: (provider: AuthButtonProvider) => void;
26+
signInGateVersion?: AuxiaGateVersion;
2527
};
2628

2729
type AuthProviderButtonProps = {
@@ -35,13 +37,13 @@ type AuthProviderButtonProps = {
3537
// The gap between elements in the main section of MinimalLayout.
3638
export const SECTION_GAP = remSpace[3]; // 12px
3739

38-
export const mainSectionStyles = css`
40+
export const mainSectionStyles = (signInGateVersion: AuxiaGateVersion) => css`
3941
display: flex;
4042
flex-direction: column;
4143
gap: ${SECTION_GAP};
4244
4345
${from.phablet} {
44-
flex-direction: row;
46+
flex-direction: ${signInGateVersion === 'v1' ? 'row' : 'column'};
4547
}
4648
`;
4749

@@ -152,10 +154,11 @@ export const AuthProviderButtons = ({
152154
isNativeApp,
153155
providers,
154156
onClick,
157+
signInGateVersion = 'v1',
155158
}: AuthProviderButtonsProps) => {
156159
const buttonOrder = getButtonOrder(isNativeApp);
157160
return (
158-
<div css={mainSectionStyles}>
161+
<div css={mainSectionStyles(signInGateVersion)}>
159162
{providers.includes('social') &&
160163
buttonOrder.map((socialProvider) => (
161164
<SocialButton

dotcom-rendering/src/components/SignInGate/SignInGate.stories.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,56 @@ export const signInGateSelectorStoryNoTreatment = () => {
261261

262262
signInGateSelectorStoryNoTreatment.storyName =
263263
'sign_in_gate_selector_no_treatment';
264+
265+
export const auxiaV2DismissibleModal = () => {
266+
return (
267+
<Section fullWidth={true}>
268+
<SignInGateSelector
269+
isPaidContent={false}
270+
isPreview={false}
271+
pageId="dismissable-v2"
272+
host="https://www.theguardian.com"
273+
idUrl="https://profile.theguardian.com"
274+
contributionsServiceUrl="https://contributions.guardianapis.com"
275+
signInGateVersion="v2"
276+
auxiaGateDisplayData={{
277+
browserId: 'test-browser-id',
278+
auxiaData: {
279+
responseId: 'test-response-id',
280+
userTreatment:
281+
mockAuxiaResponseDismissible.data.userTreatment,
282+
},
283+
}}
284+
/>
285+
</Section>
286+
);
287+
};
288+
289+
auxiaV2DismissibleModal.storyName = 'sign_in_gate_auxia_v2_modal_dismissible';
290+
291+
export const auxiaV2NonDismissibleModal = () => {
292+
return (
293+
<Section fullWidth={true}>
294+
<SignInGateSelector
295+
isPaidContent={false}
296+
isPreview={false}
297+
pageId="non-dismissable-v2"
298+
host="https://www.theguardian.com"
299+
idUrl="https://profile.theguardian.com"
300+
contributionsServiceUrl="https://contributions.guardianapis.com"
301+
signInGateVersion="v2"
302+
auxiaGateDisplayData={{
303+
browserId: 'test-browser-id',
304+
auxiaData: {
305+
responseId: 'test-response-id',
306+
userTreatment:
307+
mockAuxiaResponseNonDismissible.data.userTreatment,
308+
},
309+
}}
310+
/>
311+
</Section>
312+
);
313+
};
314+
315+
auxiaV2NonDismissibleModal.storyName =
316+
'sign_in_gate_auxia_v2_modal_non_dismissible';

dotcom-rendering/src/components/SignInGate/gateDesigns/SignInGateAuxia.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,9 @@ export const SignInGateAuxia = ({
5050
return input !== '';
5151
};
5252

53-
/*
54-
Whether the gate is dismissible is carried by `secondCtaName` which if it's truthy
55-
makes the gate dismissible and otherwise is non dismissible.
56-
*/
57-
58-
const isDismissible = !!secondCtaName;
53+
const isDismissible = userTreatment.treatmentType.startsWith(
54+
'DISMISSABLE_SIGN_IN_GATE',
55+
);
5956
const dismissStatusLabel = isDismissible
6057
? 'dismissible'
6158
: 'non-dismissible';
@@ -105,7 +102,7 @@ export const SignInGateAuxia = ({
105102
renderingTarget,
106103
abTest,
107104
);
108-
void logTreatmentInteractionCall('DISMISSED', '');
105+
void logTreatmentInteractionCall('DISMISSED');
109106
}}
110107
>
111108
{secondCtaName}

dotcom-rendering/src/components/SignInGate/gateDesigns/SignInGateAuxiaV1.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
textSansBold15,
1111
} from '@guardian/source/foundations';
1212
import { SvgCross, SvgGuardianLogo } from '@guardian/source/react-components';
13+
import { has } from '../../../lib/has-string';
1314
import { AuthProviderButtons } from '../../AuthProviderButtons/AuthProviderButtons';
1415
import { useConfig } from '../../ConfigContext';
1516
import { ExternalLink } from '../../ExternalLink/ExternalLink';
@@ -47,9 +48,9 @@ export const SignInGateAuxiaV1 = ({
4748
first_cta_link: firstCtaLink,
4849
} = JSON.parse(userTreatment.treatmentContent) as TreatmentContentDecoded;
4950

50-
const has = (s?: string) => !!s && s.trim() !== '';
51-
const isDismissible =
52-
userTreatment.treatmentType === 'DISMISSABLE_SIGN_IN_GATE';
51+
const isDismissible = userTreatment.treatmentType.startsWith(
52+
'DISMISSABLE_SIGN_IN_GATE',
53+
);
5354
const dismissStatusLabel = isDismissible
5455
? 'dismissible'
5556
: 'non-dismissible';
@@ -74,7 +75,7 @@ export const SignInGateAuxiaV1 = ({
7475
renderingTarget,
7576
abTest,
7677
);
77-
void logTreatmentInteractionCall('DISMISSED', '');
78+
void logTreatmentInteractionCall('DISMISSED');
7879
}}
7980
>
8081
<SvgCross size="xsmall" />

0 commit comments

Comments
 (0)