fix: handle webviews

This commit is contained in:
Christel Westerberg
2024-07-15 09:49:21 +02:00
parent 73cea4ba51
commit c7446032fe
12 changed files with 86 additions and 53 deletions

View File

@@ -1,8 +1,8 @@
import { serverClient } from "@/lib/trpc/server" import { serverClient } from "@/lib/trpc/server"
import TrackingSDK from "@/components/Current/TrackingSDK"
import Content from "@/components/MyPages/AccountPage/Content" import Content from "@/components/MyPages/AccountPage/Content"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import TrackingSDK from "@/components/TrackingSDK"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import styles from "./page.module.css" import styles from "./page.module.css"
@@ -19,10 +19,8 @@ export default async function MyPages({
return null return null
} }
const accountPageTracking = const accountPageTracking = serverClient().contentstack.accountPage.tracking()
await serverClient().contentstack.accountPage.tracking() const userTrackingData = serverClient().user.tracking()
const userTrackingData = await serverClient().user.tracking()
return ( return (
<main className={styles.blocks}> <main className={styles.blocks}>
@@ -32,7 +30,10 @@ export default async function MyPages({
) : ( ) : (
<p>{formatMessage({ id: "No content published" })}</p> <p>{formatMessage({ id: "No content published" })}</p>
)} )}
<TrackingSDK pageData={accountPageTracking} userData={userTrackingData} /> <TrackingSDK
pageDataPromise={accountPageTracking}
userDataPromise={userTrackingData}
/>
</main> </main>
) )
} }

View File

@@ -2,14 +2,16 @@ import "./profileLayout.css"
import { serverClient } from "@/lib/trpc/server" import { serverClient } from "@/lib/trpc/server"
import TrackingSDK from "@/components/Current/TrackingSDK" import TrackingSDK from "@/components/TrackingSDK"
export default async function ProfilePage() { export default async function ProfilePage() {
const accountPageTracking = const accountPageTracking = serverClient().contentstack.accountPage.tracking()
await serverClient().contentstack.accountPage.tracking() const userTrackingData = serverClient().user.tracking()
const userTrackingData = await serverClient().user.tracking()
return ( return (
<TrackingSDK pageData={accountPageTracking} userData={userTrackingData} /> <TrackingSDK
pageDataPromise={accountPageTracking}
userDataPromise={userTrackingData}
/>
) )
} }

View File

@@ -14,9 +14,9 @@ function getLoginType(user: User) {
// } // }
if (user?.login_with.includes("@")) { if (user?.login_with.includes("@")) {
return LoginTypeEnum.Email return LoginTypeEnum.email
} else { } else {
return LoginTypeEnum.MembershipNumber return LoginTypeEnum["membership number"]
} }
} }
@@ -176,7 +176,6 @@ export const config = {
access_token: new_tokens.access_token, access_token: new_tokens.access_token,
expires_at: new_tokens.expires_at, expires_at: new_tokens.expires_at,
refresh_token: new_tokens.refresh_token ?? token.refresh_token, refresh_token: new_tokens.refresh_token ?? token.refresh_token,
loginType,
} }
} catch (error) { } catch (error) {
console.log("token-debug Error thrown when trying to refresh", { console.log("token-debug Error thrown when trying to refresh", {

View File

@@ -1,10 +1,10 @@
import { serverClient } from "@/lib/trpc/server" import { serverClient } from "@/lib/trpc/server"
import TrackingSDK from "@/components/Current/TrackingSDK"
import { Blocks } from "@/components/Loyalty/Blocks" import { Blocks } from "@/components/Loyalty/Blocks"
import Sidebar from "@/components/Loyalty/Sidebar" import Sidebar from "@/components/Loyalty/Sidebar"
import MaxWidth from "@/components/MaxWidth" import MaxWidth from "@/components/MaxWidth"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import TrackingSDK from "@/components/TrackingSDK"
import styles from "./loyaltyPage.module.css" import styles from "./loyaltyPage.module.css"
@@ -12,15 +12,13 @@ import type { LangParams } from "@/types/params"
export default async function LoyaltyPage({ lang }: LangParams) { export default async function LoyaltyPage({ lang }: LangParams) {
const loyaltyPage = await serverClient().contentstack.loyaltyPage.get() const loyaltyPage = await serverClient().contentstack.loyaltyPage.get()
if (!loyaltyPage) { if (!loyaltyPage) {
return null return null
} }
const loyaltyPageTracking = const loyaltyPageTracking = serverClient().contentstack.loyaltyPage.tracking()
await serverClient().contentstack.loyaltyPage.tracking() const userTracking = serverClient().user.tracking()
const userTracking = await serverClient().user.tracking()
return ( return (
<section className={styles.content}> <section className={styles.content}>
{loyaltyPage.sidebar.length ? ( {loyaltyPage.sidebar.length ? (
@@ -33,7 +31,10 @@ export default async function LoyaltyPage({ lang }: LangParams) {
<Blocks blocks={loyaltyPage.blocks} lang={lang} /> <Blocks blocks={loyaltyPage.blocks} lang={lang} />
) : null} ) : null}
</MaxWidth> </MaxWidth>
<TrackingSDK pageData={loyaltyPageTracking} userData={userTracking} /> <TrackingSDK
pageDataPromise={loyaltyPageTracking}
userDataPromise={userTracking}
/>
</section> </section>
) )
} }

View File

@@ -5,6 +5,7 @@
padding-right: var(--Spacing-x0); padding-right: var(--Spacing-x0);
position: relative; position: relative;
justify-content: center; justify-content: center;
align-items: flex-start;
} }
.blocks { .blocks {
@@ -27,7 +28,6 @@
.content:has(> aside) .blocks { .content:has(> aside) .blocks {
grid-column: 2 / -1; grid-column: 2 / -1;
height: fit-content;
} }
.blocks { .blocks {

View File

@@ -6,6 +6,7 @@ import { serverClient } from "@/lib/trpc/server"
import MaxWidth from "@/components/MaxWidth" import MaxWidth from "@/components/MaxWidth"
import Content from "@/components/MyPages/AccountPage/Webview/Content" import Content from "@/components/MyPages/AccountPage/Webview/Content"
import TrackingSDK from "@/components/TrackingSDK"
import LinkToOverview from "@/components/Webviews/LinkToOverview" import LinkToOverview from "@/components/Webviews/LinkToOverview"
import styles from "./accountPage.module.css" import styles from "./accountPage.module.css"
@@ -14,16 +15,24 @@ import { LangParams } from "@/types/params"
export default async function MyPages({ lang }: LangParams) { export default async function MyPages({ lang }: LangParams) {
const accountPage = await serverClient().contentstack.accountPage.get() const accountPage = await serverClient().contentstack.accountPage.get()
if (!accountPage) { if (!accountPage) {
return null return null
} }
const accountPageTracking = serverClient().contentstack.accountPage.tracking()
const userTrackingData = serverClient().user.tracking()
const linkToOverview = `/${lang}/webview${accountPage.url}` !== overview[lang] const linkToOverview = `/${lang}/webview${accountPage.url}` !== overview[lang]
return ( return (
<MaxWidth className={styles.blocks} tag="main"> <MaxWidth className={styles.blocks} tag="main">
{linkToOverview ? <LinkToOverview lang={lang} /> : null} {linkToOverview ? <LinkToOverview lang={lang} /> : null}
<Content lang={lang} content={accountPage.content} /> <Content lang={lang} content={accountPage.content} />
<TrackingSDK
pageDataPromise={accountPageTracking}
userDataPromise={userTrackingData}
/>
</MaxWidth> </MaxWidth>
) )
} }

View File

@@ -1,9 +1,9 @@
import { serverClient } from "@/lib/trpc/server" import { serverClient } from "@/lib/trpc/server"
import { Blocks } from "@/components/Loyalty/Blocks/WebView" import { Blocks } from "@/components/Loyalty/Blocks/WebView"
import Sidebar from "@/components/Loyalty/Sidebar"
import MaxWidth from "@/components/MaxWidth" import MaxWidth from "@/components/MaxWidth"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import TrackingSDK from "@/components/TrackingSDK"
import LinkToOverview from "@/components/Webviews/LinkToOverview" import LinkToOverview from "@/components/Webviews/LinkToOverview"
import styles from "./loyaltyPage.module.css" import styles from "./loyaltyPage.module.css"
@@ -12,21 +12,25 @@ import { LangParams } from "@/types/params"
export default async function AboutScandicFriends({ lang }: LangParams) { export default async function AboutScandicFriends({ lang }: LangParams) {
const loyaltyPage = await serverClient().contentstack.loyaltyPage.get() const loyaltyPage = await serverClient().contentstack.loyaltyPage.get()
if (!loyaltyPage) { if (!loyaltyPage) {
return null return null
} }
const loyaltyPageTracking = serverClient().contentstack.loyaltyPage.tracking()
const userTrackingData = serverClient().user.tracking()
return ( return (
<section className={styles.content}> <section className={styles.content}>
<LinkToOverview lang={lang} /> <LinkToOverview lang={lang} />
{loyaltyPage.sidebar.length ? (
<Sidebar blocks={loyaltyPage.sidebar} lang={lang} />
) : null}
<MaxWidth tag="main" className={styles.blocks}> <MaxWidth tag="main" className={styles.blocks}>
<Title>{loyaltyPage.heading}</Title> <Title>{loyaltyPage.heading}</Title>
<Blocks blocks={loyaltyPage.blocks} lang={lang} /> <Blocks blocks={loyaltyPage.blocks} lang={lang} />
</MaxWidth> </MaxWidth>
<TrackingSDK
pageDataPromise={loyaltyPageTracking}
userDataPromise={userTrackingData}
/>
</section> </section>
) )
} }

View File

@@ -4,11 +4,6 @@
gap: var(--Spacing-x5); gap: var(--Spacing-x5);
} }
.sidebar {
margin-left: calc(var(--Spacing-x2) * -1);
margin-right: calc(var(--Spacing-x2) * -1);
}
.blocks { .blocks {
display: grid; display: grid;
gap: var(--Spacing-x5); gap: var(--Spacing-x5);

View File

@@ -1,7 +1,9 @@
"use client" "use client"
import { usePathname } from "next/navigation" import { usePathname } from "next/navigation"
import { useEffect } from "react" import { useCallback, useEffect } from "react"
import { webviews } from "@/constants/routes/webviews"
import { import {
SiteSectionObject, SiteSectionObject,
@@ -14,8 +16,7 @@ function createSDKPageObject(trackingData: TrackingSDKData) {
.split("/") .split("/")
.filter((seg: string) => seg) .filter((seg: string) => seg)
function getSiteSections(segments: string[]): SiteSectionObject { /*
/*
Adobe expects the properties sitesection1 - sitessection6, hence the for-loop below Adobe expects the properties sitesection1 - sitessection6, hence the for-loop below
The segments ['explore-scandic', 'wifi'] should result in: The segments ['explore-scandic', 'wifi'] should result in:
{ {
@@ -27,20 +28,18 @@ function createSDKPageObject(trackingData: TrackingSDKData) {
sitesection6: "explore-scandic|wifi||||", sitesection6: "explore-scandic|wifi||||",
} }
*/ */
const sitesections = {} as SiteSectionObject const siteSections = {} as SiteSectionObject
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
const key = ("sitesection" + (i + 1)) as keyof SiteSectionObject const key = ("sitesection" + (i + 1)) as keyof SiteSectionObject
sitesections[key] = segments.slice(0, i + 1).join("|") siteSections[key] = segments.slice(0, i + 1).join("|")
if (i > 0 && !segments[i]) { if (i > 0 && !segments[i]) {
sitesections[key] = sitesections[key].concat( siteSections[key] = siteSections[key].concat(
"|".repeat(i + 1 - segments.length) "|".repeat(i + 1 - segments.length)
) )
}
} }
return sitesections
} }
const siteSections = getSiteSections(segments)
const { host: domain } = window.location const { host: domain } = window.location
const page_obj = { const page_obj = {
event: "pageView", event: "pageView",
@@ -62,12 +61,16 @@ function createSDKPageObject(trackingData: TrackingSDKData) {
export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) { export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) {
const pathName = usePathname() const pathName = usePathname()
const isWebview = webviews.includes(pathName)
function CookiebotCallbackOnAccept() { const CookiebotCallbackOnAccept = useCallback(() => {
const cookie = window._satellite.cookie.get("CookieConsent") const cookie = window._satellite.cookie.get("CookieConsent")
if (window.Cookiebot?.changed && window.adobe) { if (window.Cookiebot?.changed && window.adobe) {
if (cookie?.includes("statistics:true")) { // For webviews we always set the consent to true since we don't have cookiebot.
if (isWebview) {
window.adobe.optIn.approve(window.adobe.OptInCategories.ANALYTICS, true)
} else if (cookie?.includes("statistics:true")) {
window.adobe.optIn.approve(window.adobe.OptInCategories.ANALYTICS, true) window.adobe.optIn.approve(window.adobe.OptInCategories.ANALYTICS, true)
} else { } else {
window.adobe.optIn.deny(window.adobe.OptInCategories.ANALYTICS, true) window.adobe.optIn.deny(window.adobe.OptInCategories.ANALYTICS, true)
@@ -76,7 +79,7 @@ export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) {
console.warn("window.load event explicitly dispatched.") console.warn("window.load event explicitly dispatched.")
window.dispatchEvent(new Event("load")) window.dispatchEvent(new Event("load"))
} }
} }, [isWebview])
function CookebotCallbackOnDecline() { function CookebotCallbackOnDecline() {
if (window.Cookiebot?.changed && window.adobe) { if (window.Cookiebot?.changed && window.adobe) {
@@ -104,7 +107,7 @@ export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) {
CookebotCallbackOnDecline CookebotCallbackOnDecline
) )
} }
}, []) }, [CookiebotCallbackOnAccept])
return null return null
} }

View File

@@ -0,0 +1,16 @@
import TrackingSDKClient from "./Client"
import { TrackingSDKProps } from "@/types/components/tracking"
export default async function TrackingSDK({
pageDataPromise,
userDataPromise,
}: {
pageDataPromise: Promise<TrackingSDKProps["pageData"]>
userDataPromise: Promise<TrackingSDKProps["userData"]>
}) {
const pageData = await pageDataPromise
const userData = await userDataPromise
return <TrackingSDKClient pageData={pageData} userData={userData} />
}

View File

@@ -18,8 +18,8 @@ export type TrackingSDKPageData = {
} }
export enum LoginTypeEnum { export enum LoginTypeEnum {
Email = "email", email = "email",
MembershipNumber = "membership number", "membership number" = "membership number",
// MagicLink = "magic link", // MagicLink = "magic link",
} }
export type LoginType = keyof typeof LoginTypeEnum export type LoginType = keyof typeof LoginTypeEnum

3
types/jwt.d.ts vendored
View File

@@ -1,3 +1,5 @@
import { LoginType } from "./components/tracking"
import type { DefaultJWT } from "next-auth/jwt" import type { DefaultJWT } from "next-auth/jwt"
import type { RefreshTokenError } from "./authError" import type { RefreshTokenError } from "./authError"
@@ -10,5 +12,6 @@ declare module "next-auth/jwt" {
access_token: string access_token: string
expires_at: number expires_at: number
refresh_token: string refresh_token: string
loginType: LoginType
} }
} }