Merged in feat/LOY-615-cleanup-env-prof-consent (pull request #3537)
feat(LOY-615): cleanup profiling consent env var * feat(LOY-615): cleanup profiling consent env var Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -1,12 +1,7 @@
|
|||||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||||
import {
|
import { getEurobonusMembership } from "@scandic-hotels/trpc/routers/user/helpers"
|
||||||
getEurobonusMembership,
|
|
||||||
scandicMembershipTypes,
|
|
||||||
} from "@scandic-hotels/trpc/routers/user/helpers"
|
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
|
||||||
import {
|
import {
|
||||||
getBasicProfileSafely,
|
|
||||||
getProfileSafely,
|
getProfileSafely,
|
||||||
getProfilingConsent,
|
getProfilingConsent,
|
||||||
} from "@/lib/trpc/memoizedRequests"
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
@@ -26,15 +21,7 @@ type MyPagesLayoutProps = React.PropsWithChildren<{
|
|||||||
breadcrumbs: React.ReactNode
|
breadcrumbs: React.ReactNode
|
||||||
}>
|
}>
|
||||||
|
|
||||||
export default async function MyPagesLayout(props: MyPagesLayoutProps) {
|
export default async function MyPagesLayout({
|
||||||
if (env.ENABLE_PROFILE_CONSENT) {
|
|
||||||
return <MyPagesLayoutWithConsent {...props} />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <MyPagesLayoutBase {...props} />
|
|
||||||
}
|
|
||||||
|
|
||||||
async function MyPagesLayoutWithConsent({
|
|
||||||
breadcrumbs,
|
breadcrumbs,
|
||||||
children,
|
children,
|
||||||
}: MyPagesLayoutProps) {
|
}: MyPagesLayoutProps) {
|
||||||
@@ -84,25 +71,3 @@ async function MyPagesLayoutWithConsent({
|
|||||||
</ProfilingConsentAlertProvider>
|
</ProfilingConsentAlertProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function MyPagesLayoutBase({
|
|
||||||
breadcrumbs,
|
|
||||||
children,
|
|
||||||
}: MyPagesLayoutProps) {
|
|
||||||
const profile = await getBasicProfileSafely()
|
|
||||||
const eurobonusMembership = profile?.loyalty?.memberships?.find(
|
|
||||||
(m) => m.membershipType === scandicMembershipTypes.SAS_EB
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.container}>
|
|
||||||
<div className={styles.layout}>
|
|
||||||
{breadcrumbs}
|
|
||||||
<div className={styles.content}>{children}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{eurobonusMembership && <SASLevelUpgradeCheck />}
|
|
||||||
<Surprises />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,24 +1,13 @@
|
|||||||
import { redirect } from "next/navigation"
|
|
||||||
|
|
||||||
import { profile } from "@scandic-hotels/common/constants/routes/myPages"
|
|
||||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
|
||||||
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import { ProfilingConsent } from "@/components/Forms/ProfilingConsent"
|
import { ProfilingConsent } from "@/components/Forms/ProfilingConsent"
|
||||||
import { getLang } from "@/i18n/serverContext"
|
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default async function ProfilingConsentSlot() {
|
export default async function ProfilingConsentSlot() {
|
||||||
const lang = await getLang()
|
|
||||||
|
|
||||||
if (!env.ENABLE_PROFILE_CONSENT) {
|
|
||||||
redirect(profile[lang])
|
|
||||||
}
|
|
||||||
|
|
||||||
const caller = await serverClient()
|
const caller = await serverClient()
|
||||||
const accountPage = await caller.contentstack.accountPage.get()
|
const accountPage = await caller.contentstack.accountPage.get()
|
||||||
const user = await getProfile()
|
const user = await getProfile()
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { env } from "@/env/server"
|
|
||||||
|
|
||||||
import SignupForm from "@/components/Forms/Signup"
|
import SignupForm from "@/components/Forms/Signup"
|
||||||
|
|
||||||
import type { SignupFormWrapperProps } from "@/types/components/blocks/dynamicContent"
|
import type { SignupFormWrapperProps } from "@/types/components/blocks/dynamicContent"
|
||||||
@@ -7,10 +5,5 @@ import type { SignupFormWrapperProps } from "@/types/components/blocks/dynamicCo
|
|||||||
export default async function SignupFormWrapper({
|
export default async function SignupFormWrapper({
|
||||||
dynamic_content,
|
dynamic_content,
|
||||||
}: SignupFormWrapperProps) {
|
}: SignupFormWrapperProps) {
|
||||||
return (
|
return <SignupForm {...dynamic_content} />
|
||||||
<SignupForm
|
|
||||||
{...dynamic_content}
|
|
||||||
enableProfileConsent={env.ENABLE_PROFILE_CONSENT}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,14 +48,9 @@ import styles from "./form.module.css"
|
|||||||
|
|
||||||
interface SignUpFormProps {
|
interface SignUpFormProps {
|
||||||
title: string
|
title: string
|
||||||
enableProfileConsent?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SignupForm({
|
export default function SignupForm({ title }: SignUpFormProps) {
|
||||||
title,
|
|
||||||
// Handled as a prop rather than a client env var due to limits in Netlify env var size.
|
|
||||||
enableProfileConsent = false,
|
|
||||||
}: SignUpFormProps) {
|
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
@@ -140,7 +135,7 @@ export default function SignupForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.formWrapper}>
|
<div className={styles.formWrapper}>
|
||||||
{enableProfileConsent && <ProfilingConsentModalReadOnly />}
|
<ProfilingConsentModalReadOnly />
|
||||||
{title ? (
|
{title ? (
|
||||||
<Typography variant="Title/md">
|
<Typography variant="Title/md">
|
||||||
<h2>{title}</h2>
|
<h2>{title}</h2>
|
||||||
@@ -293,41 +288,39 @@ export default function SignupForm({
|
|||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{enableProfileConsent && (
|
<section className={styles.personalization}>
|
||||||
<section className={styles.personalization}>
|
<header>
|
||||||
<header>
|
<Typography variant="Title/Subtitle/md">
|
||||||
<Typography variant="Title/Subtitle/md">
|
<h3>
|
||||||
<h3>
|
{intl.formatMessage({
|
||||||
{intl.formatMessage({
|
id: "signup.UnlockYourPersonalizedExperience",
|
||||||
id: "signup.UnlockYourPersonalizedExperience",
|
defaultMessage: "Unlock your personalized experience!",
|
||||||
defaultMessage: "Unlock your personalized experience!",
|
})}
|
||||||
})}
|
</h3>
|
||||||
</h3>
|
</Typography>
|
||||||
</Typography>
|
</header>
|
||||||
</header>
|
<Checkbox
|
||||||
<Checkbox
|
name="profilingConsent"
|
||||||
name="profilingConsent"
|
registerOptions={{ required: true }}
|
||||||
registerOptions={{ required: true }}
|
>
|
||||||
>
|
{intl.formatMessage({
|
||||||
{intl.formatMessage({
|
id: "signup.yesConsent",
|
||||||
id: "signup.yesConsent",
|
defaultMessage:
|
||||||
defaultMessage:
|
"I consent to Scandic using my information to give me even more personalized travel inspiration and offers from Scandic and trusted Scandic Friends partners. This means Scandic may use information about my interactions with Scandic Friends partners, and share details of my interactions with Scandic with those partners, to make the experience even more relevant to me.",
|
||||||
"I consent to Scandic using my information to give me even more personalized travel inspiration and offers from Scandic and trusted Scandic Friends partners. This means Scandic may use information about my interactions with Scandic Friends partners, and share details of my interactions with Scandic with those partners, to make the experience even more relevant to me.",
|
})}
|
||||||
})}
|
</Checkbox>
|
||||||
</Checkbox>
|
<TextLinkButton
|
||||||
<TextLinkButton
|
typography="Link/sm"
|
||||||
typography="Link/sm"
|
color="Primary"
|
||||||
color="Primary"
|
className={styles.personalizationButton}
|
||||||
className={styles.personalizationButton}
|
onClick={openPersonalizationModal}
|
||||||
onClick={openPersonalizationModal}
|
>
|
||||||
>
|
{intl.formatMessage({
|
||||||
{intl.formatMessage({
|
id: "signup.ReadMoreAboutPersonalization",
|
||||||
id: "signup.ReadMoreAboutPersonalization",
|
defaultMessage: "Read more about personalization at Scandic",
|
||||||
defaultMessage: "Read more about personalization at Scandic",
|
})}
|
||||||
})}
|
</TextLinkButton>
|
||||||
</TextLinkButton>
|
</section>
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<section className={styles.terms}>
|
<section className={styles.terms}>
|
||||||
<header>
|
<header>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { env } from "@/env/server"
|
|
||||||
|
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
import { Section } from "../Section"
|
import { Section } from "../Section"
|
||||||
@@ -17,7 +15,7 @@ export async function CommunicationSettings() {
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<EmailSlot />
|
<EmailSlot />
|
||||||
{env.ENABLE_PROFILE_CONSENT && <PersonalizationSlot />}
|
<PersonalizationSlot />
|
||||||
</Section>
|
</Section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
|
||||||
import { getProfile, getProfilingConsent } from "@/lib/trpc/memoizedRequests"
|
import { getProfile, getProfilingConsent } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { GetMainIconByCSIdentifier, userHasConsent } from "../utils"
|
import { GetMainIconByCSIdentifier, userHasConsent } from "../utils"
|
||||||
@@ -9,8 +8,6 @@ import { BannerButton } from "./Button"
|
|||||||
import styles from "./profilingConsentBanner.module.css"
|
import styles from "./profilingConsentBanner.module.css"
|
||||||
|
|
||||||
export async function ProfilingConsentBanner() {
|
export async function ProfilingConsentBanner() {
|
||||||
if (!env.ENABLE_PROFILE_CONSENT) return null
|
|
||||||
|
|
||||||
const user = await getProfile()
|
const user = await getProfile()
|
||||||
if (!user || userHasConsent(user?.profilingConsent)) return null
|
if (!user || userHasConsent(user?.profilingConsent)) return null
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Profiling Consent
|
# Profiling Consent
|
||||||
|
|
||||||
Profiling consent allows users to opt in/out of personalized experiences. The feature is controlled by the `ENABLE_PROFILE_CONSENT` environment variable.
|
Profiling consent allows users to opt in/out of personalized experiences.
|
||||||
|
|
||||||
## User Journey
|
## User Journey
|
||||||
|
|
||||||
@@ -121,11 +121,9 @@ Replace `<memberKey>` with the actual `membershipNumber` or `profileId`.
|
|||||||
Required content for the feature:
|
Required content for the feature:
|
||||||
|
|
||||||
1. **Profiling Consent (config)**
|
1. **Profiling Consent (config)**
|
||||||
|
|
||||||
- Config needs to be created and published in each language
|
- Config needs to be created and published in each language
|
||||||
|
|
||||||
2. **/consent (account page)**
|
2. **/consent (account page)**
|
||||||
|
|
||||||
- Page needs to be created and published in each language
|
- Page needs to be created and published in each language
|
||||||
|
|
||||||
3. **/overview (account page)**
|
3. **/overview (account page)**
|
||||||
|
|||||||
6
apps/scandic-web/env/server.ts
vendored
6
apps/scandic-web/env/server.ts
vendored
@@ -96,11 +96,6 @@ export const env = createEnv({
|
|||||||
.refine((s) => s === "1" || s === "0")
|
.refine((s) => s === "1" || s === "0")
|
||||||
.transform((s) => s === "1")
|
.transform((s) => s === "1")
|
||||||
.default("0"),
|
.default("0"),
|
||||||
ENABLE_PROFILE_CONSENT: z
|
|
||||||
.string()
|
|
||||||
.refine((s) => s === "true" || s === "false")
|
|
||||||
.transform((s) => s === "true")
|
|
||||||
.default("false"),
|
|
||||||
RELEASE_TAG: z
|
RELEASE_TAG: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
@@ -160,7 +155,6 @@ export const env = createEnv({
|
|||||||
DTMC_ENTRA_ID_SECRET: process.env.DTMC_ENTRA_ID_SECRET,
|
DTMC_ENTRA_ID_SECRET: process.env.DTMC_ENTRA_ID_SECRET,
|
||||||
CHATBOT_LIVE_LANGS: process.env.CHATBOT_LIVE_LANGS,
|
CHATBOT_LIVE_LANGS: process.env.CHATBOT_LIVE_LANGS,
|
||||||
SEO_INERT: process.env.SEO_INERT,
|
SEO_INERT: process.env.SEO_INERT,
|
||||||
ENABLE_PROFILE_CONSENT: process.env.ENABLE_PROFILE_CONSENT,
|
|
||||||
RELEASE_TAG: process.env.NEXT_PUBLIC_RELEASE_TAG,
|
RELEASE_TAG: process.env.NEXT_PUBLIC_RELEASE_TAG,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user