Merged in feat/LOY-486-consent-prompt-date (pull request #3221)
Feat/LOY-486 consent prompt date * chore(LOY-486): update name on date * chore(LOY-486): open links in new tab * chore(LOY-486): send prompt date + refactor modal * chore(LOY-486): update README Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { AnimatePresence, motion } from "motion/react"
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { useCallback, useEffect, useRef, useState } from "react"
|
||||
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import ScandicLogoIcon from "@scandic-hotels/design-system/Icons/ScandicLogoIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
import { trpc } from "@scandic-hotels/trpc/client"
|
||||
|
||||
import { useUpdateProfilingConsent } from "@/hooks/useUpdateProfilingConsent"
|
||||
import {
|
||||
@@ -35,6 +36,52 @@ type ProfilingConsentModalProps = {
|
||||
|
||||
const MotionModal = motion.create(Modal)
|
||||
|
||||
function usePromptInitialization(memberKey: string | undefined) {
|
||||
const utils = trpc.useUtils()
|
||||
|
||||
const updateConsentPromptDate =
|
||||
trpc.user.profilingConsentPromptDate.update.useMutation({
|
||||
onSuccess: () => utils.user.get.invalidate(),
|
||||
})
|
||||
|
||||
const mutationRef = useRef(updateConsentPromptDate)
|
||||
mutationRef.current = updateConsentPromptDate
|
||||
|
||||
const [shouldOpenInitially, setShouldOpenInitially] = useState(false)
|
||||
const hasSentPromptDate = useRef(false)
|
||||
|
||||
const sendPromptDate = useCallback((date: string) => {
|
||||
mutationRef.current.mutate({
|
||||
profilingConsentPromptDate: date,
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!memberKey) return
|
||||
|
||||
const dismissed = readDismissed(memberKey)
|
||||
const firstOpen = !dismissed
|
||||
|
||||
setShouldOpenInitially(firstOpen)
|
||||
|
||||
if (firstOpen && !hasSentPromptDate.current) {
|
||||
hasSentPromptDate.current = true
|
||||
sendPromptDate(new Date().toISOString())
|
||||
}
|
||||
}, [memberKey, sendPromptDate])
|
||||
|
||||
return shouldOpenInitially
|
||||
}
|
||||
|
||||
function useModalEvents(setOpen: (s: boolean) => void) {
|
||||
useEffect(() => {
|
||||
const handleOpen: EventListener = () => setOpen(true)
|
||||
window.addEventListener(profilingConsentOpenEvent, handleOpen)
|
||||
return () =>
|
||||
window.removeEventListener(profilingConsentOpenEvent, handleOpen)
|
||||
}, [setOpen])
|
||||
}
|
||||
|
||||
export default function ProfilingConsentModal({
|
||||
memberKey,
|
||||
content,
|
||||
@@ -42,22 +89,20 @@ export default function ProfilingConsentModal({
|
||||
readOnly = false,
|
||||
}: ProfilingConsentModalProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
const [activeChoice, setActiveChoice] = useState<boolean | null>(null)
|
||||
|
||||
const shouldOpenInitially = usePromptInitialization(memberKey)
|
||||
|
||||
const { initiateUpdateConsent, isLoading, isSuccess } =
|
||||
useUpdateProfilingConsent()
|
||||
|
||||
const [activeChoice, setActiveChoice] = useState<boolean | null>(null)
|
||||
|
||||
const handleClick = (consent: boolean) => {
|
||||
setActiveChoice(consent)
|
||||
initiateUpdateConsent(consent)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!memberKey) return
|
||||
setOpen(!readDismissed(memberKey))
|
||||
}, [memberKey])
|
||||
if (shouldOpenInitially) setOpen(true)
|
||||
}, [shouldOpenInitially])
|
||||
|
||||
useModalEvents(setOpen)
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
if (memberKey) {
|
||||
@@ -66,29 +111,22 @@ export default function ProfilingConsentModal({
|
||||
setOpen(false)
|
||||
}, [memberKey])
|
||||
|
||||
useEffect(() => {
|
||||
const handleOpen: EventListener = () => setOpen(true)
|
||||
window.addEventListener(profilingConsentOpenEvent, handleOpen)
|
||||
return () => {
|
||||
window.removeEventListener(profilingConsentOpenEvent, handleOpen)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isSuccess) onClose()
|
||||
}, [isSuccess, onClose])
|
||||
|
||||
if (!memberKey && !readOnly) return null
|
||||
|
||||
const handleConsentClick = (consent: boolean) => {
|
||||
setActiveChoice(consent)
|
||||
initiateUpdateConsent(consent)
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalOverlay
|
||||
className={styles.overlay}
|
||||
isOpen={open}
|
||||
onOpenChange={(isOpen) => {
|
||||
if (!isOpen) {
|
||||
onClose()
|
||||
}
|
||||
}}
|
||||
onOpenChange={(state) => !state && onClose()}
|
||||
isKeyboardDismissDisabled
|
||||
isDismissable={false}
|
||||
>
|
||||
@@ -185,7 +223,7 @@ export default function ProfilingConsentModal({
|
||||
position: "modal",
|
||||
name: "accept personalization",
|
||||
})
|
||||
handleClick(true)
|
||||
handleConsentClick(true)
|
||||
}}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
@@ -203,7 +241,7 @@ export default function ProfilingConsentModal({
|
||||
isPending={isLoading && activeChoice === false}
|
||||
onClick={() => {
|
||||
trackConsentAction({ position: "modal", name: "decline" })
|
||||
handleClick(false)
|
||||
handleConsentClick(false)
|
||||
}}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
|
||||
Reference in New Issue
Block a user