Merge pull request #24923 from overleaf/dp-mj-papers-notification

Add notification banner for Papers integration marketing

GitOrigin-RevId: 625c3afcc6ca617fd01af58a05a6c85f7126398b
This commit is contained in:
Mathias Jakobsen
2025-04-17 08:05:19 +00:00
committed by Copybot
parent 34d5564abc
commit 8fc206073b
6 changed files with 125 additions and 1 deletions
@@ -115,7 +115,7 @@ async function projectListPage(req, res, next) {
})
const user = await User.findById(
userId,
`email emails features alphaProgram betaProgram lastPrimaryEmailCheck signUpDate${
`email emails features alphaProgram betaProgram lastPrimaryEmailCheck signUpDate refProviders${
isSaas ? ' enrollment writefull completedTutorials' : ''
}`
)
@@ -126,6 +126,8 @@ async function projectListPage(req, res, next) {
return
}
user.refProviders = _.mapValues(user.refProviders, Boolean)
if (isSaas) {
await SplitTestSessionHandler.promises.sessionMaintenance(req, user)
@@ -418,6 +420,15 @@ async function projectListPage(req, res, next) {
'sidebar-navigation-ui-update'
)
// Get the user's assignment for the papers notification banner split test,
// which populates splitTestVariants with a value for the split test name and
// allows Pug to send it to the browser
await SplitTestHandler.promises.getAssignment(
req,
res,
'papers-notification-banner'
)
res.render('project/list-react', {
title: 'your_projects',
usersBestSubscription,
@@ -122,6 +122,7 @@
"all_projects_will_be_transferred_immediately": "",
"all_these_experiments_are_available_exclusively": "",
"allows_to_search_by_author_title_etc_possible_to_pull_results_directly_from_your_reference_manager_if_connected": "",
"already_have_a_papers_account": "",
"already_subscribed_try_refreshing_the_page": "",
"an_email_has_already_been_sent_to": "",
"an_error_occured_while_restoring_project": "",
@@ -1862,6 +1863,7 @@
"try_for_free": "",
"try_it_for_free": "",
"try_now": "",
"try_papers_for_free": "",
"try_premium_for_free": "",
"try_recompile_project_or_troubleshoot": "",
"try_relinking_provider": "",
@@ -2072,6 +2074,7 @@
"you_can_manage_your_reference_manager_integrations_from_your_account_settings_page": "",
"you_can_now_enable_sso": "",
"you_can_now_log_in_sso": "",
"you_can_now_sync_your_papers_library_directly_with_your_overleaf_projects": "",
"you_can_request_a_maximum_of_limit_fixes_per_day": "",
"you_can_select_or_invite_collaborator": "",
"you_can_select_or_invite_collaborator_plural": "",
@@ -0,0 +1,16 @@
import { useFeatureFlag } from '@/shared/context/split-test-context'
import getMeta from '@/utils/meta'
export const usePapersNotification = () => {
const user = getMeta('ol-user')
const inRollout = useFeatureFlag('papers-notification-banner')
const shouldShow =
inRollout &&
user &&
user.features?.references &&
!user.refProviders?.mendeley &&
!user.refProviders?.zotero &&
!user.refProviders?.papers
return { shouldShow }
}
@@ -0,0 +1,86 @@
import { memo, useCallback, useEffect } from 'react'
import Notification from './notification'
import { Trans, useTranslation } from 'react-i18next'
import OLButton from '@/features/ui/components/ol/ol-button'
import usePersistedState from '@/shared/hooks/use-persisted-state'
import { sendMB } from '@/infrastructure/event-tracking'
function PapersNotificationBanner() {
const { t } = useTranslation()
const [dismissed, setDismissed] = usePersistedState(
'papers-notification-banner-dismissed',
false
)
useEffect(() => {
if (!dismissed) {
sendMB('promo-prompt', {
location: 'dashboard-banner',
name: 'papers-integration',
})
}
}, [dismissed])
const handleClose = useCallback(() => {
sendMB('promo-dismiss', {
location: 'dashboard-banner',
name: 'papers-integration',
})
setDismissed(true)
}, [setDismissed])
const handlePapersButtonClick = useCallback(() => {
sendMB('promo-click', {
location: 'dashboard-banner',
name: 'papers-integration',
type: 'click-try-for-free',
})
}, [])
const handleSettingsLinkClick = useCallback(() => {
sendMB('promo-click', {
location: 'dashboard-banner',
name: 'papers-integration',
type: 'click-link-account',
})
}, [])
if (dismissed) return null
return (
<Notification
type="info"
title={t(
'you_can_now_sync_your_papers_library_directly_with_your_overleaf_projects'
)}
onDismiss={handleClose}
content={
<p>
<Trans
i18nKey="already_have_a_papers_account"
components={[
// eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
<a
onClick={handleSettingsLinkClick}
href="/user/settings#references"
/>,
]}
/>
</p>
}
action={
<OLButton
variant="secondary"
onClick={handlePapersButtonClick}
href="https://www.papersapp.com/30-day-trial/?utm_source=overleaf_inproduct&utm_medium=referral&utm_campaign=overleaf_integration"
target="_blank"
rel="noreferrer"
>
{t('try_papers_for_free')}
</OLButton>
}
/>
)
}
export default memo(PapersNotificationBanner)
@@ -13,6 +13,8 @@ import {
DeprecatedBrowser,
isDeprecatedBrowser,
} from '@/shared/components/deprecated-browser'
import PapersNotificationBanner from './papers-notification-banner'
import { usePapersNotification } from './hooks/use-papers-notification'
const [enrollmentNotificationModule] = importOverleafModules(
'managedGroupSubscriptionEnrollmentNotification'
@@ -32,6 +34,8 @@ function UserNotifications() {
const groupSubscriptionsPendingEnrollment =
getMeta('ol-groupSubscriptionsPendingEnrollment') || []
const { shouldShow: showPapersNotificationBanner } = usePapersNotification()
return (
<div className="user-notifications notification-list">
<ul className="list-unstyled">
@@ -52,6 +56,7 @@ function UserNotifications() {
<GroupsAndEnterpriseBanner />
{USGovBanner && <USGovBanner />}
{showPapersNotificationBanner && <PapersNotificationBanner />}
<AccessibilitySurveyBanner />
{isDeprecatedBrowser() && <DeprecatedBrowser />}
+3
View File
@@ -148,6 +148,7 @@
"all_the_pros_of_our_standard_plan_plus_unlimited_collab": "All the pros of our standard plan, plus unlimited collaborators per project.",
"all_these_experiments_are_available_exclusively": "All these experiments are available exclusively to members of the Labs program. If you sign up, you can choose which experiments you want to try.",
"allows_to_search_by_author_title_etc_possible_to_pull_results_directly_from_your_reference_manager_if_connected": "Allows to search by author, title, etc. Possible to pull results directly from your reference manager (if connected).",
"already_have_a_papers_account": "Managing your citations and bibliographies in Overleaf just got way easier! Already have a Papers account? <0>Link your account here</0>.",
"already_have_an_account": "Already have an account?",
"already_have_sl_account": "Already have an __appName__ account?",
"already_subscribed_try_refreshing_the_page": "Already subscribed? Try refreshing the page.",
@@ -2392,6 +2393,7 @@
"try_for_free": "Try for free",
"try_it_for_free": "Try it for free",
"try_now": "Try Now",
"try_papers_for_free": "Try Papers for free",
"try_premium_for_free": "Try Premium for free",
"try_recompile_project_or_troubleshoot": "Please try recompiling the project from scratch, and if that doesnt help, follow our <0>troubleshooting guide</0>.",
"try_relinking_provider": "It looks like you need to re-link your __provider__ account.",
@@ -2628,6 +2630,7 @@
"you_can_manage_your_reference_manager_integrations_from_your_account_settings_page": "You can manage your reference manager integrations from your <0>account settings page</0>.",
"you_can_now_enable_sso": "You can now enable SSO on your Group settings page.",
"you_can_now_log_in_sso": "You can now log in through your institution and if eligible you will receive <0>__appName__ Professional features</0>.",
"you_can_now_sync_your_papers_library_directly_with_your_overleaf_projects": "You can now sync your Papers library directly with your Overleaf projects",
"you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page": "You can <0>opt in and out</0> of the program at any time on this page",
"you_can_request_a_maximum_of_limit_fixes_per_day": "You can request a maximum of __limit__ fixes per day. Please try again tomorrow.",
"you_can_select_or_invite_collaborator": "You can select or invite __count__ collaborator on your current plan. Upgrade to add more editors or reviewers.",