plans.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import '../../../marketing'
  2. import '../../../features/plans/group-plan-modal'
  3. import * as eventTracking from '../../../infrastructure/event-tracking'
  4. import getMeta from '../../../utils/meta'
  5. const PLANS_PAGE_LAYOUT_V2_ANNUAL = 'plans-page-layout-v2-annual'
  6. let currentView = 'monthly'
  7. let currentCurrencyCode = getMeta('ol-recommendedCurrency')
  8. function selectView(view) {
  9. document.querySelectorAll('[data-ol-view-tab]').forEach(el => {
  10. if (el.getAttribute('data-ol-view-tab') === view) {
  11. el.classList.add('active')
  12. } else {
  13. el.classList.remove('active')
  14. }
  15. })
  16. document.querySelectorAll('[data-ol-view]').forEach(el => {
  17. el.hidden = el.getAttribute('data-ol-view') !== view
  18. })
  19. updateAnnualSavingBanner(view)
  20. currentView = view
  21. updateLinkTargets()
  22. }
  23. function setUpViewSwitching(liEl) {
  24. const plansPageV2SplitTestVariant =
  25. getMeta('ol-splitTestVariants')?.[PLANS_PAGE_LAYOUT_V2_ANNUAL] ?? 'default'
  26. const view = liEl.getAttribute('data-ol-view-tab')
  27. liEl.querySelector('a').addEventListener('click', function (e) {
  28. e.preventDefault()
  29. eventTracking.send('subscription-funnel', 'plans-page', `${view}-prices`)
  30. eventTracking.sendMB('plans-page-toggle', {
  31. button: view,
  32. PLANS_PAGE_LAYOUT_V2_ANNUAL: plansPageV2SplitTestVariant,
  33. })
  34. selectView(view)
  35. })
  36. }
  37. function setUpCurrencySwitching(linkEl) {
  38. const currencyCode = linkEl.getAttribute('data-ol-currencyCode-switch')
  39. linkEl.addEventListener('click', function (e) {
  40. e.preventDefault()
  41. document.querySelectorAll('[data-ol-currencyCode]').forEach(el => {
  42. el.hidden = el.getAttribute('data-ol-currencyCode') !== currencyCode
  43. })
  44. currentCurrencyCode = currencyCode
  45. eventTracking.sendMB('plans-page-currency', { currency: currencyCode })
  46. updateLinkTargets()
  47. })
  48. }
  49. function setUpSubscriptionTracking(linkEl) {
  50. const plansPageV2SplitTestVariant =
  51. getMeta('ol-splitTestVariants')?.[PLANS_PAGE_LAYOUT_V2_ANNUAL] ?? 'default'
  52. const plan =
  53. linkEl.getAttribute('data-ol-tracking-plan') ||
  54. linkEl.getAttribute('data-ol-start-new-subscription')
  55. const location = linkEl.getAttribute('data-ol-location')
  56. const period = linkEl.getAttribute('data-ol-item-view') || currentView
  57. const DEFAULT_EVENT_TRACKING_KEY = 'plans-page-click'
  58. const eventTrackingKey =
  59. linkEl.getAttribute('data-ol-event-tracking-key') ||
  60. DEFAULT_EVENT_TRACKING_KEY
  61. const eventTrackingSegmentation = {
  62. button: plan,
  63. location,
  64. period,
  65. }
  66. if (eventTrackingKey === DEFAULT_EVENT_TRACKING_KEY) {
  67. eventTrackingSegmentation[PLANS_PAGE_LAYOUT_V2_ANNUAL] =
  68. plansPageV2SplitTestVariant
  69. }
  70. linkEl.addEventListener('click', function () {
  71. const customLabel = linkEl.getAttribute('data-ol-tracking-label')
  72. const computedLabel = currentView === 'annual' ? `${plan}_annual` : plan
  73. const label = customLabel || computedLabel
  74. eventTracking.sendMB('plans-page-start-trial') // deprecated by plans-page-click
  75. eventTracking.send('subscription-funnel', 'sign_up_now_button', label) // deprecated by plans-page-click
  76. eventTracking.sendMB(eventTrackingKey, eventTrackingSegmentation)
  77. })
  78. }
  79. const searchParams = new URLSearchParams(window.location.search)
  80. export function updateLinkTargets() {
  81. document.querySelectorAll('[data-ol-start-new-subscription]').forEach(el => {
  82. if (el.hasAttribute('data-ol-has-custom-href')) return
  83. const plan = el.getAttribute('data-ol-start-new-subscription')
  84. const view = el.getAttribute('data-ol-item-view') || currentView
  85. const suffix = view === 'annual' ? `-annual` : `_free_trial_7_days`
  86. const planCode = `${plan}${suffix}`
  87. const location = el.getAttribute('data-ol-location')
  88. const itmCampaign = searchParams.get('itm_campaign') || 'plans'
  89. const itmContent =
  90. itmCampaign === 'plans' ? location : searchParams.get('itm_content')
  91. const queryString = new URLSearchParams({
  92. planCode,
  93. currency: currentCurrencyCode,
  94. itm_campaign: itmCampaign,
  95. })
  96. if (itmContent) {
  97. queryString.set('itm_content', itmContent)
  98. }
  99. el.href = `/user/subscription/new?${queryString.toString()}`
  100. })
  101. }
  102. function updateAnnualSavingBanner(view) {
  103. const tooltipEl = document.querySelector('[data-ol-annual-saving-tooltip]')
  104. if (view === 'annual') {
  105. tooltipEl.classList.add('annual-selected')
  106. } else {
  107. tooltipEl.classList.remove('annual-selected')
  108. }
  109. }
  110. function selectViewFromHash() {
  111. try {
  112. const params = new URLSearchParams(window.location.hash.substring(1))
  113. const view = params.get('view')
  114. if (view) {
  115. // make sure the selected view is valid
  116. if (document.querySelector(`[data-ol-view-tab="${view}"]`)) {
  117. selectView(view)
  118. // clear the hash so it doesn't persist when switching plans
  119. window.location.hash = ''
  120. }
  121. }
  122. } catch {
  123. // do nothing
  124. }
  125. }
  126. document.querySelectorAll('[data-ol-view-tab]').forEach(setUpViewSwitching)
  127. document
  128. .querySelectorAll('[data-ol-currencyCode-switch]')
  129. .forEach(setUpCurrencySwitching)
  130. document
  131. .querySelectorAll('[data-ol-start-new-subscription]')
  132. .forEach(setUpSubscriptionTracking)
  133. updateLinkTargets()
  134. selectViewFromHash()
  135. window.addEventListener('hashchange', selectViewFromHash)