@newskit-render/core 1.66.0 → 1.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +16 -0
  3. package/__tests__/pages/[articleSlug].test.tsx +1 -55
  4. package/__tests__/pages/__snapshots__/home.test.tsx.snap +657 -626
  5. package/__tests__/pages/__snapshots__/relatedArticles.test.tsx.snap +651 -0
  6. package/__tests__/pages/relatedArticles.test.tsx +23 -11
  7. package/components/article/__tests__/__snapshots__/index.test.tsx.snap +1091 -1060
  8. package/components/footer/index.tsx +1 -1
  9. package/components/header/banner-messages.ts +45 -0
  10. package/components/header/index.tsx +31 -287
  11. package/components/header/navigation-links.ts +20 -0
  12. package/components/layout/LayoutTemplate.tsx +4 -1
  13. package/config/__tests__/index.test.ts +53 -0
  14. package/config/environment.ts +67 -0
  15. package/config/index.ts +2 -85
  16. package/config/multiTenancy.ts +12 -0
  17. package/{app-context → context/app-context}/AppContext.test.tsx +7 -3
  18. package/{app-context/AppContext.tsx → context/app-context/index.tsx} +5 -1
  19. package/context/index.tsx +2 -0
  20. package/context/multi-tenancy/MultiTenancy.test.tsx +47 -0
  21. package/context/multi-tenancy/index.tsx +31 -0
  22. package/css/index.ts +224 -0
  23. package/cypress/support/commands.js +8 -4
  24. package/helpers/__tests__/createThemeDropdownObject.test.ts +3 -3
  25. package/helpers/__tests__/getRecommendation.test.ts +62 -0
  26. package/helpers/createThemeDropdownObject.ts +3 -3
  27. package/helpers/getRecommendations.ts +29 -0
  28. package/helpers/global-types.ts +8 -0
  29. package/{__tests__/pages/mocks.ts → helpers/mocks/getRecommendationsMock.ts} +2 -6
  30. package/helpers/multiTenancy.ts +19 -0
  31. package/jest.config.js +1 -2
  32. package/package.json +11 -9
  33. package/pages/[section]/[articleId]/[articleSlug].tsx +17 -10
  34. package/pages/[section]/[articleId]/relatedArticles.tsx +49 -40
  35. package/pages/_app.tsx +42 -257
  36. package/pages/account/cancellation/index.tsx +1 -1
  37. package/pages/account/edit/[field].tsx +1 -1
  38. package/pages/account/index.tsx +1 -1
  39. package/pages/account/newsletters-and-alerts/index.tsx +1 -1
  40. package/pages/account/payment/index.tsx +1 -1
  41. package/pages/account/subscription-and-billing/index.tsx +1 -1
  42. package/pages/api/auth/[...nextauth].ts +5 -1
  43. package/pages/api/recommendations/[...slug].ts +21 -0
  44. package/pages/checkout/account-creation/index.tsx +1 -1
  45. package/pages/checkout/payment-details/index.tsx +1 -1
  46. package/pages/help-hub/[id]/index.tsx +22 -9
  47. package/pages/help-hub/index.tsx +22 -9
  48. package/pages/help-hub/results.tsx +24 -0
  49. package/theme/strings/demo.ts +1 -0
  50. package/theme/strings/index.ts +1 -0
  51. package/components/header/index.test.tsx +0 -73
@@ -1,10 +1,8 @@
1
1
  import React from 'react'
2
2
  import newrelic from 'newrelic'
3
- import { getAcsCookie, ClientTypes, Publisher } from '@newskit-render/api'
4
- import {
5
- recommendationsProvider,
6
- Article,
7
- } from '@newskit-render/standalone-components'
3
+ import useSWR from 'swr'
4
+ import { getAcsCookie, ClientTypes } from '@newskit-render/api'
5
+ import { Article } from '@newskit-render/standalone-components'
8
6
  import { Block, Cell, TitleBar } from 'newskit'
9
7
  import { UserData } from '@newskit-render/my-account'
10
8
  import { fetchUser } from '../../../helpers/getUser'
@@ -12,45 +10,58 @@ import { ACCOUNT_QUERY_URL } from '../../../constants'
12
10
  import { addCacheHeaders } from '../../../helpers/addCacheHeaders'
13
11
  import Layout from '../../../components/layout'
14
12
  import { BasicRow } from '../../../components/section/layouts'
13
+ import { fetcher } from '../../../helpers/getRecommendations'
15
14
 
16
15
  export type RelatedArticles = {
17
16
  user?: UserData
18
- recommendations: Article[]
17
+ articleId
19
18
  }
20
19
 
21
20
  const RelatedArticlesPage: React.FC<RelatedArticles> = ({
22
21
  user,
23
- recommendations,
24
- }) => (
25
- <Layout dataTestId="SectionGrid" user={user}>
26
- <Cell xs={12} md={10} mdOffset={1} data-testid="SectionCell">
27
- <Block spaceStack="space080" />
28
- <Block spaceStack="space080">
29
- <TitleBar
30
- overrides={{
31
- spaceInset: {
32
- xs: 'spaceInsetSquish000',
33
- },
34
- heading: {
35
- typographyPreset: {
36
- xs: 'editorialHeadline050',
37
- md: 'editorialHeadline060',
38
- xl: 'editorialHeadline070',
22
+ articleId,
23
+ }) => {
24
+ let userId: string
25
+ if (typeof window !== 'undefined') {
26
+ userId = window?.utag?.data['cp.utag_main_v_id']
27
+ }
28
+
29
+ const { data: recommendationData = [] } = useSWR<Article[]>(
30
+ `/api/recommendations/${articleId}/${userId}`,
31
+ fetcher
32
+ )
33
+ const recommendations = recommendationData.slice(0, 18)
34
+ return (
35
+ <Layout dataTestId="SectionGrid" user={user}>
36
+ <Cell xs={12} md={10} mdOffset={1} data-testid="SectionCell">
37
+ <Block spaceStack="space080" />
38
+ <Block spaceStack="space080">
39
+ <TitleBar
40
+ overrides={{
41
+ spaceInset: {
42
+ xs: 'spaceInsetSquish000',
39
43
  },
40
- stylePreset: 'inkContrast',
41
- },
42
- }}
43
- >
44
- Related Articles
45
- </TitleBar>
46
- </Block>
47
- <BasicRow
48
- colums={{ xs: '1fr', md: '1fr 1fr', lg: '1fr 1fr 1fr' }}
49
- articles={recommendations}
50
- />
51
- </Cell>
52
- </Layout>
53
- )
44
+ heading: {
45
+ typographyPreset: {
46
+ xs: 'editorialHeadline050',
47
+ md: 'editorialHeadline060',
48
+ xl: 'editorialHeadline070',
49
+ },
50
+ stylePreset: 'inkContrast',
51
+ },
52
+ }}
53
+ >
54
+ Related Articles
55
+ </TitleBar>
56
+ </Block>
57
+ <BasicRow
58
+ colums={{ xs: '1fr', md: '1fr 1fr', lg: '1fr 1fr 1fr' }}
59
+ articles={recommendations}
60
+ />
61
+ </Cell>
62
+ </Layout>
63
+ )
64
+ }
54
65
 
55
66
  export async function getServerSideProps(context) {
56
67
  newrelic.setTransactionName('RelatedArticlesPage')
@@ -65,19 +76,17 @@ export async function getServerSideProps(context) {
65
76
  ? getAcsCookie(ClientTypes.main, context.req.headers.cookie)
66
77
  : ''
67
78
 
68
- const [recommendations, user] = await Promise.all([
69
- await recommendationsProvider({ articleId, publisher: Publisher.SUN_UK }),
79
+ const [user] = await Promise.all([
70
80
  await fetchUser(acsCookie, ACCOUNT_QUERY_URL),
71
81
  ])
72
82
 
73
83
  addCacheHeaders(context.res)
74
84
 
75
- const recommendationsToShow = recommendations.slice(0, 18)
76
85
  return {
77
86
  props: {
78
- recommendations: recommendationsToShow,
79
87
  showAds: true,
80
88
  user,
89
+ articleId,
81
90
  },
82
91
  }
83
92
  }
package/pages/_app.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { AppProps } from 'next/app'
2
+ import { AppContext as AppContextType, AppProps } from 'next/app'
3
3
  import Head from 'next/head'
4
4
  import { ThemeProvider, Global, css, styled } from 'newskit'
5
5
  import { SessionProvider } from '@newskit-render/auth'
@@ -9,10 +9,14 @@ import {
9
9
  FeatureFlag,
10
10
  createFeatureFlagsInstance,
11
11
  } from '@newskit-render/feature-flags'
12
- import { AppContextProvider, AppContext } from '../app-context/AppContext'
12
+ import { Publisher } from '@newskit-render/api'
13
+ import { AppContextProvider, AppContext } from '../context/app-context'
13
14
  import { logger } from '../helpers/logger'
14
15
 
15
16
  import { optimizelysdkKey } from '../config'
17
+ import { getTenant } from '../helpers/multiTenancy'
18
+ import { GlobalStyling } from '../css'
19
+ import MultiTenancyProvider from '../context/multi-tenancy'
16
20
 
17
21
  if (!process.browser) {
18
22
  // eslint-disable-next-line global-require
@@ -26,229 +30,6 @@ if (optimizelysdkKey) {
26
30
  })
27
31
  }
28
32
 
29
- const GlobalStyling = css`
30
- @font-face {
31
- font-family: GillSansMTStd-Medium;
32
- src: url('/fonts/GillSansMTStd-Medium.otf');
33
- }
34
- @font-face {
35
- font-family: TimesModern-Bold;
36
- src: url('/fonts/TimesDigital-Bold.ttf') format('truetype');
37
- }
38
- @font-face {
39
- font-family: TimesModern-Regular;
40
- src: url('/fonts/TimesDigital-Regular.ttf') format('truetype');
41
- }
42
- @font-face {
43
- font-family: TimesDigitalW04-Regular;
44
- src: url('/fonts/TimesDigitalW04-Regular.ttf') format('truetype');
45
- }
46
- @font-face {
47
- font-family: Montserrat;
48
- src: url('/fonts/Montserrat-Regular.ttf') format('truetype');
49
- }
50
- @font-face {
51
- font-family: TheSun-Bold;
52
- src: url('/fonts/TheSun-Bold.ttf') format('truetype');
53
- }
54
- @font-face {
55
- font-family: TheSun-HeavyNarrow;
56
- src: url('/fonts/TheSun-HeavyNarrow.ttf') format('truetype');
57
- }
58
- @font-face {
59
- font-family: TheSun-Regular;
60
- src: url('/fonts/TheSun-Regular.ttf') format('truetype');
61
- }
62
- @font-face {
63
- font-family: TheSun-Medium;
64
- src: url('/fonts/TheSun-Medium.ttf') format('truetype');
65
- }
66
- @font-face {
67
- font-family: 'DM Sans';
68
- src: url('/fonts/dmsans-regular-webfont.woff2') format('woff2'),
69
- url('/fonts/dmsans-regular-webfont.woff') format('woff');
70
- font-style: normal;
71
- font-weight: 400;
72
- font-display: swap;
73
- }
74
- @font-face {
75
- font-family: 'DM Sans';
76
- src: url('/fonts/dmsans-italic-webfont.woff2') format('woff2'),
77
- url('/fonts/dmsans-italic-webfont.woff') format('woff');
78
- font-style: italic;
79
- font-weight: 400;
80
- font-display: swap;
81
- }
82
- @font-face {
83
- font-family: 'DM Sans';
84
- src: url('/fonts/dmsans-medium-webfont.woff2') format('woff2'),
85
- url('/fonts/dmsans-medium-webfont.woff') format('woff');
86
- font-style: normal;
87
- font-weight: 500;
88
- font-display: swap;
89
- }
90
- @font-face {
91
- font-family: 'DM Sans';
92
- src: url('/fonts/dmsans-mediumitalic-webfont.woff2') format('woff2'),
93
- url('/fonts/dmsans-mediumitalic-webfont.woff') format('woff');
94
- font-style: italic;
95
- font-weight: 500;
96
- font-display: swap;
97
- }
98
- @font-face {
99
- font-family: 'DM Sans';
100
- src: url('/fonts/dmsans-bold-webfont.woff2') format('woff2'),
101
- url('/fonts/dmsans-bold-webfont.woff') format('woff');
102
- font-style: normal;
103
- font-weight: 700;
104
- font-display: swap;
105
- }
106
- @font-face {
107
- font-family: 'DM Sans';
108
- src: url('/fonts/dmsans-bolditalic-webfont.woff2') format('woff2'),
109
- url('/fonts/dmsans-bolditalic-webfont.woff') format('woff');
110
- font-style: italic;
111
- font-weight: 700;
112
- font-display: swap;
113
- }
114
- @font-face {
115
- font-family: 'Poppins';
116
- src: url('/fonts/poppins-bold-webfont.woff2') format('woff2'),
117
- url('/fonts/poppins-bold-webfont.woff') format('woff');
118
- font-weight: 700;
119
- font-style: normal;
120
- }
121
- @font-face {
122
- font-family: 'Poppins';
123
- src: url('/fonts/poppins-bolditalic-webfont.woff2') format('woff2'),
124
- url('/fonts/poppins-bolditalic-webfont.woff') format('woff');
125
- font-weight: normal;
126
- font-style: italic;
127
- }
128
- @font-face {
129
- font-family: 'Poppins';
130
- src: url('/fonts/poppins-extrabold-webfont.woff2') format('woff2'),
131
- url('/fonts/poppins-extrabold-webfont.woff') format('woff');
132
- font-weight: 800;
133
- font-style: normal;
134
- }
135
- @font-face {
136
- font-family: 'Poppins';
137
- src: url('/fonts/poppins-extrabolditalic-webfont.woff2') format('woff2'),
138
- url('/fonts/poppins-extrabolditalic-webfont.woff') format('woff');
139
- font-weight: 800;
140
- font-style: italic;
141
- }
142
- @font-face {
143
- font-family: 'Poppins';
144
- src: url('/fonts/poppins-italic-webfont.woff2') format('woff2'),
145
- url('/fonts/poppins-italic-webfont.woff') format('woff');
146
- font-weight: 400;
147
- font-style: italic;
148
- }
149
- @font-face {
150
- font-family: 'Poppins';
151
- src: url('/fonts/poppins-light-webfont.woff2') format('woff2'),
152
- url('/fonts/poppins-light-webfont.woff') format('woff');
153
- font-weight: 300;
154
- font-style: normal;
155
- }
156
- @font-face {
157
- font-family: 'Poppins';
158
- src: url('/fonts/poppins-lightitalic-webfont.woff2') format('woff2'),
159
- url('/fonts/poppins-lightitalic-webfont.woff') format('woff');
160
- font-weight: 300;
161
- font-style: italic;
162
- }
163
- @font-face {
164
- font-family: 'Poppins';
165
- src: url('/fonts/poppins-medium-webfont.woff2') format('woff2'),
166
- url('/fonts/poppins-medium-webfont.woff') format('woff');
167
- font-weight: 500;
168
- font-style: normal;
169
- }
170
- @font-face {
171
- font-family: 'Poppins';
172
- src: url('/fonts/poppins-mediumitalic-webfont.woff2') format('woff2'),
173
- url('/fonts/poppins-mediumitalic-webfont.woff') format('woff');
174
- font-weight: 500;
175
- font-style: italic;
176
- }
177
- @font-face {
178
- font-family: 'Poppins';
179
- src: url('/fonts/poppins-regular-webfont.woff2') format('woff2'),
180
- url('/fonts/poppins-regular-webfont.woff') format('woff');
181
- font-weight: 400;
182
- font-style: normal;
183
- }
184
- @font-face {
185
- font-family: 'Poppins';
186
- src: url('/fonts/poppins-semibold-webfont.woff2') format('woff2'),
187
- url('/fonts/poppins-semibold-webfont.woff') format('woff');
188
- font-weight: 600;
189
- font-style: normal;
190
- }
191
- @font-face {
192
- font-family: 'Poppins';
193
- src: url('/fonts/poppins-semibolditalic-webfont.woff2') format('woff2'),
194
- url('/fonts/poppins-semibolditalic-webfont.woff') format('woff');
195
- font-weight: 600;
196
- font-style: italic;
197
- }
198
- @font-face {
199
- font-family: 'DM Mono';
200
- src: url('/fonts/dmmono-medium.woff2') format('woff2'),
201
- url('/fonts/dmmono-medium.woff') format('woff');
202
- font-style: normal;
203
- font-weight: 500;
204
- font-display: swap;
205
- }
206
- @font-face {
207
- font-family: 'Bitter';
208
- src: url('/fonts/bitter-regular.woff2') format('woff2'),
209
- url('/fonts/bitter-regular.woff') format('woff');
210
- font-style: normal;
211
- font-weight: 400;
212
- font-display: swap;
213
- }
214
- @font-face {
215
- font-family: 'Bitter';
216
- src: url('/fonts/bitter-medium.woff2') format('woff2'),
217
- url('/fonts/bitter-medium.woff') format('woff');
218
- font-style: normal;
219
- font-weight: 500;
220
- font-display: swap;
221
- }
222
- @font-face {
223
- font-family: 'Bitter';
224
- src: url('/fonts/bitter-mediumitalic.woff2') format('woff2'),
225
- url('/fonts/bitter-mediumitalic.woff') format('woff');
226
- font-style: italic;
227
- font-weight: 500;
228
- font-display: swap;
229
- }
230
- @font-face {
231
- font-family: 'Bitter';
232
- src: url('/fonts/bitter-semibold.woff2') format('woff2'),
233
- url('/fonts/bitter-semibold.woff') format('woff');
234
- font-style: normal;
235
- font-weight: 600;
236
- font-display: swap;
237
- }
238
-
239
- html,
240
- body {
241
- padding: 0;
242
- margin: 0;
243
- font-family: 'Noto Sans', -apple-system, BlinkMacSystemFont, Segoe UI,
244
- Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
245
- sans-serif;
246
- }
247
- * {
248
- box-sizing: border-box;
249
- }
250
- `
251
-
252
33
  const PageContainer = styled.div`
253
34
  position: relative;
254
35
  min-height: 100vh;
@@ -256,52 +37,56 @@ const PageContainer = styled.div`
256
37
 
257
38
  interface MyAppProps extends AppProps {
258
39
  featureFlags?: FeatureFlag
40
+ tenant: Publisher
259
41
  }
260
42
 
261
- function MyApp({ Component, pageProps, featureFlags }: MyAppProps) {
43
+ function MyApp({ Component, pageProps, featureFlags, tenant }: MyAppProps) {
262
44
  return (
263
- <AppContextProvider>
264
- <>
265
- <Head>
266
- <meta name="robots" content="max-image-preview:standard" />
267
- <meta name="robots" content="max-video-preview:0" />
268
- <meta google-site-verification="google-site-verification=9IZcsqYKeNo_Wlkwq6WBqgpqZuiwPGJw90Ug_LAENt4" />
269
- <meta
270
- name="viewport"
271
- content="initial-scale=1.0, width=device-width"
272
- key="viewport"
273
- />
274
- </Head>
275
- <FeatureFlagsContextProvider context={featureFlags}>
276
- <SessionProvider pageProps={pageProps}>
277
- <AppContext.Consumer>
278
- {({ theme }) => (
279
- <ThemeProvider theme={theme}>
280
- <Global styles={GlobalStyling} />
281
- <PageContainer>
282
- <Component {...pageProps} />
283
- </PageContainer>
284
- </ThemeProvider>
285
- )}
286
- </AppContext.Consumer>
287
- </SessionProvider>
288
- </FeatureFlagsContextProvider>
289
- </>
290
- </AppContextProvider>
45
+ <MultiTenancyProvider tenant={tenant}>
46
+ <AppContextProvider>
47
+ <>
48
+ <Head>
49
+ <meta name="robots" content="max-image-preview:standard" />
50
+ <meta name="robots" content="max-video-preview:0" />
51
+ <meta google-site-verification="google-site-verification=9IZcsqYKeNo_Wlkwq6WBqgpqZuiwPGJw90Ug_LAENt4" />
52
+ <meta
53
+ name="viewport"
54
+ content="initial-scale=1.0, width=device-width"
55
+ key="viewport"
56
+ />
57
+ </Head>
58
+ <FeatureFlagsContextProvider context={featureFlags}>
59
+ <SessionProvider pageProps={pageProps}>
60
+ <AppContext.Consumer>
61
+ {({ theme }) => (
62
+ <ThemeProvider theme={theme}>
63
+ <Global styles={GlobalStyling} />
64
+ <PageContainer>
65
+ <Component {...pageProps} />
66
+ </PageContainer>
67
+ </ThemeProvider>
68
+ )}
69
+ </AppContext.Consumer>
70
+ </SessionProvider>
71
+ </FeatureFlagsContextProvider>
72
+ </>
73
+ </AppContextProvider>
74
+ </MultiTenancyProvider>
291
75
  )
292
76
  }
293
77
 
294
- MyApp.getInitialProps = async ({ Component, ctx }) => {
78
+ MyApp.getInitialProps = async ({ Component, ctx }: AppContextType) => {
295
79
  let pageProps = {}
80
+ const tenant = getTenant(ctx.req?.headers?.host)
296
81
  if (Component.getInitialProps) {
297
82
  pageProps = await Component.getInitialProps(ctx)
298
83
  }
299
84
 
300
85
  if (optimizelysdkKey) {
301
86
  const featureFlags = await getFeatureFlags()
302
- return { featureFlags, pageProps }
87
+ return { featureFlags, pageProps, tenant }
303
88
  }
304
- return { pageProps }
89
+ return { pageProps, tenant }
305
90
  }
306
91
 
307
92
  export default MyApp
@@ -1,7 +1,7 @@
1
1
  import React, { useContext } from 'react'
2
2
  import { Cancellation, getProviderProps } from '@newskit-render/my-account'
3
3
  import newrelic from 'newrelic'
4
- import { AppContext } from '../../../app-context/AppContext'
4
+ import { AppContext } from '../../../context/app-context'
5
5
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
6
6
  import validation from '../../../validation'
7
7
 
@@ -7,7 +7,7 @@ import {
7
7
  componentMap,
8
8
  } from '@newskit-render/my-account'
9
9
  import validation from '../../../validation'
10
- import { AppContext } from '../../../app-context/AppContext'
10
+ import { AppContext } from '../../../context/app-context'
11
11
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
12
12
 
13
13
  const AccountEditField = (props) => {
@@ -1,7 +1,7 @@
1
1
  import newrelic from 'newrelic'
2
2
  import { PersonalDetails, getProviderProps } from '@newskit-render/my-account'
3
3
  import React, { useContext } from 'react'
4
- import { AppContext } from '../../app-context/AppContext'
4
+ import { AppContext } from '../../context/app-context'
5
5
  import { createThemeDropdownObject } from '../../helpers/createThemeDropdownObject'
6
6
 
7
7
  const AccountPersonalDetails = (props) => {
@@ -4,7 +4,7 @@ import {
4
4
  } from '@newskit-render/my-account'
5
5
  import newrelic from 'newrelic'
6
6
  import React, { useContext } from 'react'
7
- import { AppContext } from '../../../app-context/AppContext'
7
+ import { AppContext } from '../../../context/app-context'
8
8
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
9
9
 
10
10
  const AccountNewslettersAndAlerts = (props) => {
@@ -5,7 +5,7 @@ import {
5
5
  PaymentProvider,
6
6
  } from '@newskit-render/my-account'
7
7
  import React, { useContext } from 'react'
8
- import { AppContext } from '../../../app-context/AppContext'
8
+ import { AppContext } from '../../../context/app-context'
9
9
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
10
10
 
11
11
  const AccountCancellation = (props) => {
@@ -4,7 +4,7 @@ import {
4
4
  } from '@newskit-render/my-account'
5
5
  import newrelic from 'newrelic'
6
6
  import React, { useContext } from 'react'
7
- import { AppContext } from '../../../app-context/AppContext'
7
+ import { AppContext } from '../../../context/app-context'
8
8
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
9
9
 
10
10
  const AccountSubscriptionAndBilling = (props) => {
@@ -3,4 +3,8 @@ import { NextApiRequest, NextApiResponse } from 'next'
3
3
  import { oktaClientId, oktaClientSecret, oktaDomain } from '../../../config'
4
4
 
5
5
  export default (req: NextApiRequest, res: NextApiResponse) =>
6
- createAuthRoute(req, res, { oktaClientId, oktaClientSecret, oktaDomain })
6
+ createAuthRoute(req, res, {
7
+ clientId: oktaClientId,
8
+ clientSecret: oktaClientSecret,
9
+ issuer: oktaDomain,
10
+ })
@@ -0,0 +1,21 @@
1
+ import { NextApiRequest, NextApiResponse } from 'next'
2
+ import { Publisher } from '@newskit-render/api'
3
+ import { getRecommendations } from '../../../helpers/getRecommendations'
4
+
5
+ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
6
+ try {
7
+ const [articleId, userId] = req.query.slug as string[]
8
+ const result = await getRecommendations({
9
+ articleId,
10
+ publisher: Publisher.SUN_UK,
11
+ userId,
12
+ })
13
+ res.setHeader('Content-Type', 'application/json')
14
+ res.end(JSON.stringify(result))
15
+ } catch (error) {
16
+ res.json(error)
17
+ res.status(405).end()
18
+ }
19
+ }
20
+
21
+ export default handler
@@ -1,6 +1,6 @@
1
1
  import { AccountCreation, getProviderProps } from '@newskit-render/checkout'
2
2
  import React, { useContext } from 'react'
3
- import { AppContext } from '../../../app-context/AppContext'
3
+ import { AppContext } from '../../../context/app-context'
4
4
  import validation from '../../../validation'
5
5
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { PaymentDetails, getProviderProps } from '@newskit-render/checkout'
2
2
  import React, { useContext } from 'react'
3
- import { AppContext } from '../../../app-context/AppContext'
3
+ import { AppContext } from '../../../context/app-context'
4
4
  import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
5
5
 
6
6
  const PaymentDetailsPage = (props) => {
@@ -1,11 +1,24 @@
1
- import React from 'react'
2
- import { ResultsPage } from '@newskit-render/standalone-components'
3
- import Layout from '../../../components/layout'
1
+ import React, { useContext } from 'react'
2
+ import { ArticlePage } from '@newskit-render/standalone-components'
3
+ import { createThemeDropdownObject } from '../../../helpers/createThemeDropdownObject'
4
+ import { AppContext } from '../../../context'
4
5
 
5
- const HelpHubResultsPage = () => (
6
- <Layout>
7
- <ResultsPage />
8
- </Layout>
9
- )
6
+ const HelpHubArticlePage = (props) => {
7
+ const { theme, setTheme } = useContext(AppContext)
8
+ const themeDropdownObject = createThemeDropdownObject(setTheme)
10
9
 
11
- export default HelpHubResultsPage
10
+ return (
11
+ <ArticlePage
12
+ {...props}
13
+ contextName="articlePage"
14
+ customTheme={theme}
15
+ themeDropdownObject={themeDropdownObject}
16
+ />
17
+ )
18
+ }
19
+
20
+ export default HelpHubArticlePage
21
+
22
+ // export const getServerSideProps = async (context) => {
23
+ // return getProviderProps({ ...context, provider: '' })
24
+ // }
@@ -1,11 +1,24 @@
1
- import React from 'react'
2
- import { SearchPage } from '@newskit-render/standalone-components'
3
- import Layout from '../../components/layout'
1
+ import React, { useContext } from 'react'
2
+ import { LandingPage } from '@newskit-render/standalone-components'
3
+ import { createThemeDropdownObject } from '../../helpers/createThemeDropdownObject'
4
+ import { AppContext } from '../../context'
4
5
 
5
- const HelpHub = () => (
6
- <Layout>
7
- <SearchPage />
8
- </Layout>
9
- )
6
+ const HelpHubLandingPage = (props) => {
7
+ const { theme, setTheme } = useContext(AppContext)
8
+ const themeDropdownObject = createThemeDropdownObject(setTheme)
10
9
 
11
- export default HelpHub
10
+ return (
11
+ <LandingPage
12
+ {...props}
13
+ contextName="landingPage"
14
+ customTheme={theme}
15
+ themeDropdownObject={themeDropdownObject}
16
+ />
17
+ )
18
+ }
19
+
20
+ export default HelpHubLandingPage
21
+
22
+ // export const getServerSideProps = async (context) => {
23
+ // return getProviderProps({ ...context, provider: '' })
24
+ // }