chore: Cleanup unused vars, exports, types * Cleanup some unused exports * Remove more * Readd CampaignPageIncludedHotelsRef * Add alias comment to procedure exports * Remove unused exports Approved-by: Linus Flood
4.1 KiB
Profiling Consent
Profiling consent allows users to opt in/out of personalized experiences. The feature is controlled by the ENABLE_PROFILE_CONSENT environment variable.
User Journey
- Signup: Optional consent checkbox in registration form
- My Pages Modal: Prompt shown on first visit (if no decision made)
- Banner: Shown on overview page if modal was dismissed without deciding
- Profile Settings: Dedicated page at
/profile/consentto update consent at any time
Components
Modal (Modal/)
Full-page modal shown when a user first visits a My Pages route.
- Rendered in
app/[lang]/(live)/(protected)/my-pages/layout.tsx - Only shows if user hasn't made a consent decision (
profilingConsentisundefined) - Uses
memberKey(frommembershipNumberorprofileId) for dismissal tracking - Close via "X" button only (no overlay click or ESC key)
- Accept/Decline buttons update consent via API
Sub-components:
Modal/BenefitCards/— Cards showcasing personalization benefitsModal/ReadOnly.tsx— Informational version without action buttons (used in signup)
Banner (Banner/)
Shown on the account overview page when consent is pending.
- Server component that checks
userHasConsent()before rendering - CTA button dispatches
profiling-consent:openevent to reopen the modal - Added to overview via Contentstack Dynamic Content block
Alert (Alert/)
Feedback alert shown after consent actions in My Pages.
ProfilingConsentAlertProvider— Context provider in My Pages layout- Shows success/error states after accepting/declining consent
- Success alert includes link to edit preferences
Consent Form (components/Forms/ProfilingConsent/)
Dedicated form on /profile/consent page for managing consent.
- Radio button selection for Accept/Decline
- Shows current consent status
- Redirects to profile after saving
- Includes accordion with privacy information
Signup Integration
The signup form (components/Forms/Signup/index.tsx) includes:
- Checkbox to opt-in during registration
- "Read more" link that opens
Modal/ReadOnly.tsx
Profile Settings
PersonalizationSlot in components/MyPages/Profile/CommunicationSettings/ provides a link to the consent management page.
Accordion (Accordion/)
Expandable section with privacy and personalization details. Used in both the modal and consent form.
API
tRPC Mutations
trpc.user.profilingConsent.update— Update user's consent preferencetrpc.user.profilingConsentPromptDate.update— Record when user was prompted
tRPC Queries
trpc.contentstack.profilingConsent.get— Fetch modal/banner content from CMS
Hooks
useUpdateProfilingConsent(hooks/useUpdateProfilingConsent.ts) — Handles consent update mutation with alert feedback viaProfilingConsentAlertProvider
Local Storage
Modal dismissal is tracked per-member to control auto-open behavior:
- Key:
profiling-consent:dismissed:<memberKey> - Set when modal is closed via header close button
- Does not reflect Accept/Decline (those are stored via API)
Utilities
Located at utils/profilingConsent.ts:
storageKey(memberKey)— Generate storage keyreadDismissed(memberKey)— Check if modal was dismissedsetDismissed(memberKey)— Mark modal as dismissedprofilingConsentOpenEvent— CustomEvent name for opening modalrequestOpen()— Dispatch event to open modal
Testing
Re-show modal after dismissing:
localStorage.removeItem("profiling-consent:dismissed:<memberKey>")
// Refresh the page
Open modal programmatically:
window.dispatchEvent(new CustomEvent("profiling-consent:open"))
Replace <memberKey> with the actual membershipNumber or profileId.
Contentstack Setup
Required content for the feature:
-
Profiling Consent (config)
- Config needs to be created and published in each language
-
/consent (account page)
- Page needs to be created and published in each language
-
/overview (account page)
- Add Dynamic content block: "Profiling Consent Banner"
- Re-publish the page for each language