Merged in feat/LOY-484-consent-alert (pull request #3184)
feat(LOY-484): Change toast to alert for Profiling Consent * feat(LOY-484): change toast to alert using context * refactor(LOY-484): remove uneccesary code * chore(LOY-484): small UI fixes Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
@@ -6,6 +6,8 @@ import {
|
|||||||
getProfilingConsent,
|
getProfilingConsent,
|
||||||
} from "@/lib/trpc/memoizedRequests"
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
|
import ProfilingConsentAlert from "@/components/MyPages/ProfilingConsent/Alert"
|
||||||
|
import { ProfilingConsentAlertProvider } from "@/components/MyPages/ProfilingConsent/Alert/AlertContext"
|
||||||
import ProfilingConsentModal from "@/components/MyPages/ProfilingConsent/Modal"
|
import ProfilingConsentModal from "@/components/MyPages/ProfilingConsent/Modal"
|
||||||
import { userHasConsent } from "@/components/MyPages/ProfilingConsent/utils"
|
import { userHasConsent } from "@/components/MyPages/ProfilingConsent/utils"
|
||||||
import { SASLevelUpgradeCheck } from "@/components/MyPages/SASLevelUpgradeCheck"
|
import { SASLevelUpgradeCheck } from "@/components/MyPages/SASLevelUpgradeCheck"
|
||||||
@@ -36,24 +38,32 @@ export default async function MyPagesLayout({
|
|||||||
const lang = await getLang()
|
const lang = await getLang()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<ProfilingConsentAlertProvider>
|
||||||
<div className={styles.layout}>
|
<div className={styles.container}>
|
||||||
{breadcrumbs}
|
<div className={styles.layout}>
|
||||||
<div className={styles.content}>{children}</div>
|
{breadcrumbs}
|
||||||
</div>
|
|
||||||
|
|
||||||
{eurobonusMembership && <SASLevelUpgradeCheck />}
|
<div className={styles.content}>
|
||||||
<Surprises />
|
<ProfilingConsentAlert />
|
||||||
{memberKey && profilingConsent && !hasConsent ? (
|
{children}
|
||||||
<>
|
</div>
|
||||||
<ProfilingConsentModal
|
</div>
|
||||||
memberKey={memberKey}
|
|
||||||
content={profilingConsent.modal}
|
{eurobonusMembership && <SASLevelUpgradeCheck />}
|
||||||
iconIdentifier={profilingConsent.icon}
|
<Surprises />
|
||||||
/>
|
{memberKey && profilingConsent && !hasConsent ? (
|
||||||
<TrackingSDK pageData={{ domainLanguage: lang, ...ModalTracking }} />
|
<>
|
||||||
</>
|
<ProfilingConsentModal
|
||||||
) : null}
|
memberKey={memberKey}
|
||||||
</div>
|
content={profilingConsent.modal}
|
||||||
|
iconIdentifier={profilingConsent.icon}
|
||||||
|
/>
|
||||||
|
<TrackingSDK
|
||||||
|
pageData={{ domainLanguage: lang, ...ModalTracking }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</ProfilingConsentAlertProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
padding: var(--Space-x4) var(--Space-x2) 0;
|
padding: var(--Space-x4) var(--Space-x2) 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Space-x6);
|
gap: var(--Space-x6);
|
||||||
|
|
||||||
|
border-radius: var(--Corner-radius-Medium) var(--Corner-radius-Medium) 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
@@ -20,6 +22,12 @@
|
|||||||
padding: var(--Space-x2) var(--Space-x3) var(--Space-x3) var(--Space-x3);
|
padding: var(--Space-x2) var(--Space-x3) var(--Space-x3) var(--Space-x3);
|
||||||
border-top: 1px solid var(--Border-Divider-Subtle);
|
border-top: 1px solid var(--Border-Divider-Subtle);
|
||||||
background: var(--Base-Surface-Primary-light-Normal);
|
background: var(--Base-Surface-Primary-light-Normal);
|
||||||
|
|
||||||
|
border-radius: 0 0 var(--Corner-radius-Medium) var(--Corner-radius-Medium);
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@@ -48,11 +56,19 @@
|
|||||||
.form {
|
.form {
|
||||||
padding: var(--Space-x4) var(--Space-x3) 0;
|
padding: var(--Space-x4) var(--Space-x3) 0;
|
||||||
gap: var(--Space-x6);
|
gap: var(--Space-x6);
|
||||||
|
|
||||||
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
gap: var(--Space-x2);
|
gap: var(--Space-x2);
|
||||||
padding: var(--Space-x6) var(--Space-x3) var(--Space-x4);
|
padding: var(--Space-x6) var(--Space-x3) var(--Space-x4);
|
||||||
|
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
"use client"
|
||||||
|
import { createContext, type ReactNode, useContext, useState } from "react"
|
||||||
|
|
||||||
|
import type { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
|
|
||||||
|
type AlertType = AlertTypeEnum.Success | AlertTypeEnum.Alarm
|
||||||
|
|
||||||
|
const ProfilingConsentAlertContext = createContext<{
|
||||||
|
alertType: AlertType | null
|
||||||
|
setAlertType: (data: AlertType | null) => void
|
||||||
|
}>({
|
||||||
|
alertType: null,
|
||||||
|
setAlertType: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
export function ProfilingConsentAlertProvider({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: ReactNode
|
||||||
|
}) {
|
||||||
|
const [alertType, setAlertType] = useState<AlertType | null>(null)
|
||||||
|
return (
|
||||||
|
<ProfilingConsentAlertContext.Provider value={{ alertType, setAlertType }}>
|
||||||
|
{children}
|
||||||
|
</ProfilingConsentAlertContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useProfilingConsentAlert = () =>
|
||||||
|
useContext(ProfilingConsentAlertContext)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
.alert {
|
||||||
|
height: fit-content;
|
||||||
|
margin-bottom: var(--Space-x1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { type IntlShape, useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
|
import { profileConsent } from "@scandic-hotels/common/constants/routes/myPages"
|
||||||
|
import { Alert } from "@scandic-hotels/design-system/Alert"
|
||||||
|
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
|
import { useProfilingConsentAlert } from "./AlertContext"
|
||||||
|
|
||||||
|
import styles from "./alert.module.css"
|
||||||
|
|
||||||
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
|
|
||||||
|
type AlertData = {
|
||||||
|
type: AlertTypeEnum.Success | AlertTypeEnum.Alarm
|
||||||
|
heading: string
|
||||||
|
message?: string
|
||||||
|
link?: { url: string; title: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProfilingConsentAlert() {
|
||||||
|
const { alertType, setAlertType } = useProfilingConsentAlert()
|
||||||
|
const intl = useIntl()
|
||||||
|
const lang = useLang()
|
||||||
|
|
||||||
|
if (!alertType) return null
|
||||||
|
|
||||||
|
const alert = getAlert(alertType, intl, lang)
|
||||||
|
if (!alert) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
variant="inline"
|
||||||
|
type={alert.type}
|
||||||
|
heading={alert.heading}
|
||||||
|
link={alert.link}
|
||||||
|
text={alert.message}
|
||||||
|
close={() => setAlertType(null)}
|
||||||
|
className={styles.alert}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAlert(
|
||||||
|
alertType: AlertTypeEnum,
|
||||||
|
intl: IntlShape,
|
||||||
|
lang: Lang
|
||||||
|
): AlertData | null {
|
||||||
|
switch (alertType) {
|
||||||
|
case AlertTypeEnum.Success:
|
||||||
|
return {
|
||||||
|
type: AlertTypeEnum.Success,
|
||||||
|
heading: intl.formatMessage({
|
||||||
|
id: "profilingConsent.alert.preferenceSaved",
|
||||||
|
defaultMessage: "Preference saved!",
|
||||||
|
}),
|
||||||
|
link: {
|
||||||
|
url: profileConsent[lang],
|
||||||
|
title: intl.formatMessage({
|
||||||
|
id: "profilingConsent.alert.editIn",
|
||||||
|
defaultMessage: "Edit in Personalization & Profiling",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
case AlertTypeEnum.Alarm:
|
||||||
|
return {
|
||||||
|
type: AlertTypeEnum.Alarm,
|
||||||
|
heading: intl.formatMessage({
|
||||||
|
id: "profilingConsent.alert.preferenceNotSaved",
|
||||||
|
defaultMessage: "Preference not saved!",
|
||||||
|
}),
|
||||||
|
message: intl.formatMessage({
|
||||||
|
id: "profilingConsent.alert.anErrorOcurred",
|
||||||
|
defaultMessage:
|
||||||
|
"An error occurred when updating preferences, please try again later.",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,38 +1,27 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import { toast } from "@scandic-hotels/design-system/Toast"
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
import { trpc } from "@scandic-hotels/trpc/client"
|
import { trpc } from "@scandic-hotels/trpc/client"
|
||||||
|
|
||||||
|
import { useProfilingConsentAlert } from "@/components/MyPages/ProfilingConsent/Alert/AlertContext"
|
||||||
|
|
||||||
export function useUpdateProfilingConsent() {
|
export function useUpdateProfilingConsent() {
|
||||||
const intl = useIntl()
|
|
||||||
const utils = trpc.useUtils()
|
const utils = trpc.useUtils()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const { setAlertType } = useProfilingConsentAlert()
|
||||||
|
|
||||||
const updateConsent = trpc.user.profilingConsent.update.useMutation({
|
const updateConsent = trpc.user.profilingConsent.update.useMutation({
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
await utils.user.get.invalidate()
|
await utils.user.get.invalidate()
|
||||||
router.refresh()
|
router.refresh()
|
||||||
setTimeout(() => {
|
setAlertType(AlertTypeEnum.Success)
|
||||||
toast.success(
|
|
||||||
intl.formatMessage({
|
|
||||||
id: "profilingConsent.alert.updateConsentSuccessful",
|
|
||||||
defaultMessage: "Preference saved!",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onError: () => {
|
onError: () => {
|
||||||
setTimeout(() => {
|
setAlertType(AlertTypeEnum.Alarm)
|
||||||
toast.error(
|
|
||||||
intl.formatMessage({
|
|
||||||
id: "profilingConsent.alert.updateConsentFailed",
|
|
||||||
defaultMessage:
|
|
||||||
"An error occurred when updating preferences, please try again later.",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user