mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #18419 from overleaf/mf-plans-page-permanent-url
[web] Create permanent URL for all plans and switch state in the plans page GitOrigin-RevId: 5fa0af0e33868f8fa4f6a74627bedb4c22705cb0
This commit is contained in:
parent
97469c9bef
commit
c722dcbc8d
4 changed files with 120 additions and 26 deletions
|
@ -49,7 +49,10 @@ footer.fat-footer.hidden-print.website-redesign-fat-footer
|
||||||
li
|
li
|
||||||
a(href="/for/universities") #{translate('for_universities')}
|
a(href="/for/universities") #{translate('for_universities')}
|
||||||
li
|
li
|
||||||
a(href="/user/subscription/plans?itm_referrer=footer-for-students#view=student") #{translate('for_students')}
|
a(
|
||||||
|
data-ol-for-students-link
|
||||||
|
href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
|
||||||
|
) #{translate('for_students')}
|
||||||
|
|
||||||
.footer-section
|
.footer-section
|
||||||
h2.footer-section-heading #{translate('get_involved')}
|
h2.footer-section-heading #{translate('get_involved')}
|
||||||
|
|
|
@ -49,7 +49,10 @@ footer.fat-footer.hidden-print
|
||||||
li
|
li
|
||||||
a(href="/for/universities") #{translate('for_universities')}
|
a(href="/for/universities") #{translate('for_universities')}
|
||||||
li
|
li
|
||||||
a(href="/user/subscription/plans?itm_referrer=footer-for-students#view=student") #{translate('for_students')}
|
a(
|
||||||
|
data-ol-for-students-link
|
||||||
|
href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
|
||||||
|
) #{translate('for_students')}
|
||||||
|
|
||||||
.footer-section
|
.footer-section
|
||||||
h2.footer-section-heading #{translate('get_involved')}
|
h2.footer-section-heading #{translate('get_involved')}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
export function getViewInfoFromHash() {
|
||||||
|
const hash = window.location.hash.substring(1)
|
||||||
|
|
||||||
|
switch (hash) {
|
||||||
|
case 'individual-monthly':
|
||||||
|
return ['individual', 'monthly']
|
||||||
|
case 'individual-annual':
|
||||||
|
return ['individual', 'annual']
|
||||||
|
case 'group':
|
||||||
|
return ['group', 'annual']
|
||||||
|
case 'student-monthly':
|
||||||
|
return ['student', 'monthly']
|
||||||
|
case 'student-annual':
|
||||||
|
return ['student', 'annual']
|
||||||
|
default:
|
||||||
|
return ['individual', 'monthly']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {individual | group | student} viewTab
|
||||||
|
* @param {monthly | annual} period
|
||||||
|
*/
|
||||||
|
export function setHashFromViewTab(viewTab, period) {
|
||||||
|
const newHash = viewTab === 'group' ? 'group' : `${viewTab}-${period}`
|
||||||
|
if (window.location.hash.substring(1)) {
|
||||||
|
window.location.hash = newHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is only for the students link in footer
|
||||||
|
export function handleForStudentsLinkInFooter() {
|
||||||
|
const links = document.querySelectorAll('[data-ol-for-students-link]')
|
||||||
|
|
||||||
|
links.forEach(function (link) {
|
||||||
|
link.addEventListener('click', function () {
|
||||||
|
if (window.location.pathname === '/user/subscription/plans') {
|
||||||
|
// reload location with the correct hash
|
||||||
|
const newURL =
|
||||||
|
'/user/subscription/plans?itm_referrer=footer-for-students#student-annual'
|
||||||
|
history.replaceState(null, '', newURL)
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
|
@ -13,6 +13,11 @@ import {
|
||||||
updateMainGroupPlanPricing,
|
updateMainGroupPlanPricing,
|
||||||
} from './plans-v2-group-plan'
|
} from './plans-v2-group-plan'
|
||||||
import { setUpGroupSubscriptionButtonAction } from './plans-v2-subscription-button'
|
import { setUpGroupSubscriptionButtonAction } from './plans-v2-subscription-button'
|
||||||
|
import {
|
||||||
|
getViewInfoFromHash,
|
||||||
|
handleForStudentsLinkInFooter,
|
||||||
|
setHashFromViewTab,
|
||||||
|
} from './plans-v2-hash'
|
||||||
import getMeta from '../../../../utils/meta'
|
import getMeta from '../../../../utils/meta'
|
||||||
|
|
||||||
const currentCurrencyCode = getMeta('ol-recommendedCurrency')
|
const currentCurrencyCode = getMeta('ol-recommendedCurrency')
|
||||||
|
@ -116,6 +121,9 @@ function selectTab(viewTab) {
|
||||||
updateMonthlyAnnualSwitchValue(viewTab)
|
updateMonthlyAnnualSwitchValue(viewTab)
|
||||||
|
|
||||||
toggleUniversityInfo(viewTab)
|
toggleUniversityInfo(viewTab)
|
||||||
|
|
||||||
|
// update the hash to reflect the current view when switching individual, group, or student tabs
|
||||||
|
setHashFromViewTab(viewTab, currentMonthlyAnnualSwitchValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMonthlyAnnualSwitchValue(viewTab) {
|
function updateMonthlyAnnualSwitchValue(viewTab) {
|
||||||
|
@ -190,19 +198,22 @@ function toggleUniversityInfo(viewTab) {
|
||||||
el.hidden = viewTab !== 'student'
|
el.hidden = viewTab !== 'student'
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectViewFromHash() {
|
// This is the old scheme for hashing redirection
|
||||||
|
// This is deprecated and should be removed in the future
|
||||||
|
// This is only used for backward compatibility
|
||||||
|
function selectViewFromHashDeprecated() {
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams(window.location.hash.substring(1))
|
const params = new URLSearchParams(window.location.hash.substring(1))
|
||||||
const view = params.get('view')
|
const view = params.get('view')
|
||||||
if (view) {
|
if (view) {
|
||||||
// View params are expected to be of the format e.g. individual or individual-monthly
|
// View params are expected to be of the format e.g. individual or individual-monthly
|
||||||
const [tab, cadence] = view.split('-')
|
const [tab, period] = view.split('-')
|
||||||
// make sure the selected view is valid
|
// make sure the selected view is valid
|
||||||
if (document.querySelector(`[data-ol-plans-v2-view-tab="${tab}"]`)) {
|
if (document.querySelector(`[data-ol-plans-v2-view-tab="${tab}"]`)) {
|
||||||
selectTab(tab)
|
selectTab(tab)
|
||||||
|
|
||||||
if (['monthly', 'annual'].includes(cadence)) {
|
if (['monthly', 'annual'].includes(period)) {
|
||||||
currentMonthlyAnnualSwitchValue = cadence
|
currentMonthlyAnnualSwitchValue = period
|
||||||
} else {
|
} else {
|
||||||
// set annual as the default
|
// set annual as the default
|
||||||
currentMonthlyAnnualSwitchValue = 'annual'
|
currentMonthlyAnnualSwitchValue = 'annual'
|
||||||
|
@ -210,24 +221,8 @@ function selectViewFromHash() {
|
||||||
|
|
||||||
updateMonthlyAnnualSwitchValue(tab)
|
updateMonthlyAnnualSwitchValue(tab)
|
||||||
|
|
||||||
// clear the hash so it doesn't persist when switching plans
|
// change the hash with the new scheme
|
||||||
const currentURL = window.location.pathname + window.location.search
|
setHashFromViewTab(tab, currentMonthlyAnnualSwitchValue)
|
||||||
history.replaceState('', document.title, currentURL)
|
|
||||||
|
|
||||||
// Add a small delay since it seems the scroll won't behave correctly on this scenario:
|
|
||||||
// 1. Open plans page
|
|
||||||
// 2. Click on "Group Plans"
|
|
||||||
// 3. Scroll down to footer
|
|
||||||
// 4. Click "For students" link
|
|
||||||
//
|
|
||||||
// I assume this is happening because the `selectTab` function above is doing a lot
|
|
||||||
// of computation to change the view and it somehow prevents the `window.scrollTo` command
|
|
||||||
// to behave correctly.
|
|
||||||
const SCROLL_TO_TOP_DELAY = 50
|
|
||||||
|
|
||||||
window.setTimeout(() => {
|
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
|
||||||
}, SCROLL_TO_TOP_DELAY)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -235,6 +230,35 @@ function selectViewFromHash() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectViewAndPeriodFromHash() {
|
||||||
|
const [viewTab, period] = getViewInfoFromHash()
|
||||||
|
|
||||||
|
// the sequence of these three lines is important
|
||||||
|
// because `currentMonthlyAnnualSwitchValue` is mutable.
|
||||||
|
// `selectTab` and `updateMonthlyAnnualSwitchValue` depend on the value of `currentMonthlyAnnualSwitchValue`
|
||||||
|
// to determine the UI state
|
||||||
|
currentMonthlyAnnualSwitchValue = period
|
||||||
|
selectTab(viewTab)
|
||||||
|
updateMonthlyAnnualSwitchValue(viewTab)
|
||||||
|
|
||||||
|
// handle the case where user access plans page while still on the plans page
|
||||||
|
// current example would the the "For students" link on the footer
|
||||||
|
const SCROLL_TO_TOP_DELAY = 50
|
||||||
|
window.setTimeout(() => {
|
||||||
|
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||||
|
}, SCROLL_TO_TOP_DELAY)
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the function to select the view and period from the hash value
|
||||||
|
// this is called once when the page is loaded
|
||||||
|
if (window.location.hash) {
|
||||||
|
if (window.location.hash.includes('view')) {
|
||||||
|
selectViewFromHashDeprecated()
|
||||||
|
} else {
|
||||||
|
selectViewAndPeriodFromHash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('[data-ol-plans-v2-m-a-switch]')
|
.querySelector('[data-ol-plans-v2-m-a-switch]')
|
||||||
.addEventListener('click', () => {
|
.addEventListener('click', () => {
|
||||||
|
@ -249,6 +273,15 @@ document
|
||||||
}
|
}
|
||||||
|
|
||||||
switchMonthlyAnnual(currentMonthlyAnnualSwitchValue)
|
switchMonthlyAnnual(currentMonthlyAnnualSwitchValue)
|
||||||
|
|
||||||
|
// update the hash to reflect the current view when pressing the monthly-annual switch
|
||||||
|
const DEFAULT_VIEW_TAB = 'individual'
|
||||||
|
const viewTab =
|
||||||
|
document
|
||||||
|
.querySelector('[data-ol-plans-v2-m-a-switch-container]')
|
||||||
|
.getAttribute('data-ol-current-view') ?? DEFAULT_VIEW_TAB
|
||||||
|
|
||||||
|
setHashFromViewTab(viewTab, currentMonthlyAnnualSwitchValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
document
|
document
|
||||||
|
@ -261,6 +294,14 @@ setUpMonthlyAnnualSwitching()
|
||||||
setUpGroupSubscriptionButtonAction()
|
setUpGroupSubscriptionButtonAction()
|
||||||
setUpStickyHeaderObserver()
|
setUpStickyHeaderObserver()
|
||||||
updateLinkTargets()
|
updateLinkTargets()
|
||||||
|
handleForStudentsLinkInFooter()
|
||||||
|
|
||||||
selectViewFromHash()
|
window.addEventListener('hashchange', () => {
|
||||||
window.addEventListener('hashchange', selectViewFromHash)
|
if (window.location.hash) {
|
||||||
|
if (window.location.hash.includes('view')) {
|
||||||
|
selectViewFromHashDeprecated()
|
||||||
|
} else {
|
||||||
|
selectViewAndPeriodFromHash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue