Merge pull request #16167 from overleaf/em-writefull-promo

Writefull integration 10% promo

GitOrigin-RevId: 27ef5e51d7d9c56d85ccc44692444bff46fbeeec
This commit is contained in:
Eric Mc Sween
2023-12-13 09:02:48 +00:00
committed by Copybot
parent 369d5cb406
commit ee0dbcf331
6 changed files with 282 additions and 24 deletions
@@ -5,6 +5,7 @@ import ConfirmEmail from './groups/confirm-email'
import ReconfirmationInfo from './groups/affiliation/reconfirmation-info'
import GroupsAndEnterpriseBanner from './groups-and-enterprise-banner'
import WritefullPromoBanner from './writefull-promo-banner'
import WritefullPremiumPromoBanner from './writefull-premium-promo-banner'
import GroupSsoSetupSuccess from './groups/group-sso-setup-success'
import INRBanner from './ads/inr-banner'
import LATAMBanner from './ads/latam-banner'
@@ -12,7 +13,9 @@ import getMeta from '../../../../utils/meta'
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
import customLocalStorage from '../../../../infrastructure/local-storage'
import { sendMB } from '../../../../infrastructure/event-tracking'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
const WRITEFULL_PROMO_DELAY_MS = 24 * 60 * 60 * 1000 // 1 day
const isChromium = () =>
(window.navigator as any).userAgentData?.brands?.some(
(item: { brand: string }) => item.brand === 'Chromium'
@@ -44,22 +47,52 @@ function UserNotifications() {
'unassigned'
)
const showLATAMBanner = getMeta('ol-showLATAMBanner', false)
const writefullIntegrationSplitTestEnabled = isSplitTestEnabled(
'writefull-integration'
)
// Temporary workaround to prevent also showing groups/enterprise banner
const [showWritefull, setShowWritefull] = useState(() => {
if (isChromium()) {
const show =
getMeta('ol-showWritefullPromoBanner') &&
!customLocalStorage.getItem('has_dismissed_writefull_promo_banner')
if (show) {
sendMB('promo-prompt', {
location: 'dashboard-banner',
page: '/project',
name: 'writefull',
})
}
return show
const dismissed = customLocalStorage.getItem(
'has_dismissed_writefull_promo_banner'
)
if (dismissed) {
return false
}
let show = false
if (writefullIntegrationSplitTestEnabled) {
// Show the Writefull promo 1 day after it has been enabled
const user = getMeta('ol-user')
if (user.writefull?.enabled) {
const scheduledAt = customLocalStorage.getItem(
'writefull_promo_scheduled_at'
)
if (scheduledAt == null) {
customLocalStorage.setItem(
'writefull_promo_scheduled_at',
new Date(Date.now() + WRITEFULL_PROMO_DELAY_MS).toISOString()
)
} else if (new Date() >= new Date(scheduledAt)) {
show = true
}
}
} else {
// Only show the Writefull extension promo on Chrome browsers
show = isChromium() && getMeta('ol-showWritefullPromoBanner')
}
if (show) {
sendMB('promo-prompt', {
location: 'dashboard-banner',
page: '/project',
name: writefullIntegrationSplitTestEnabled
? 'writefull-premium'
: 'writefull',
})
}
return show
})
const [dismissedWritefull, setDismissedWritefull] = useState(false)
@@ -91,13 +124,23 @@ function UserNotifications() {
splitTestName={inrGeoBannerSplitTestName}
/>
) : null}
<WritefullPromoBanner
show={showWritefull}
setShow={setShowWritefull}
onDismiss={() => {
setDismissedWritefull(true)
}}
/>
{writefullIntegrationSplitTestEnabled ? (
<WritefullPremiumPromoBanner
show={showWritefull}
setShow={setShowWritefull}
onDismiss={() => {
setDismissedWritefull(true)
}}
/>
) : (
<WritefullPromoBanner
show={showWritefull}
setShow={setShowWritefull}
onDismiss={() => {
setDismissedWritefull(true)
}}
/>
)}
</ul>
</div>
)
@@ -0,0 +1,67 @@
import { memo, useCallback } from 'react'
import Notification from '@/shared/components/notification'
import { sendMB } from '@/infrastructure/event-tracking'
import customLocalStorage from '@/infrastructure/local-storage'
import WritefullLogo from '@/shared/svgs/writefull-logo'
const eventSegmentation = {
location: 'dashboard-banner',
page: '/project',
name: 'writefull-premium',
}
function WritefullPremiumPromoBanner({
show,
setShow,
onDismiss,
}: {
show: boolean
setShow: (value: boolean) => void
onDismiss: () => void
}) {
const handleClose = useCallback(() => {
customLocalStorage.setItem(
'has_dismissed_writefull_promo_banner',
new Date()
)
customLocalStorage.removeItem('writefull_promo_scheduled_at')
setShow(false)
sendMB('promo-dismiss', eventSegmentation)
onDismiss()
}, [setShow, onDismiss])
if (!show) {
return null
}
return (
<Notification
type="info"
isDismissible
onDismiss={handleClose}
content={
<>
Enjoying Writefull? Get <strong>10% off Writefull Premium</strong>,
giving you access to TeXGPT—AI assistance to generate LaTeX code. Use{' '}
<strong>OVERLEAF10</strong> at the checkout.
</>
}
action={
<a
className="btn btn-secondary"
href="https://my.writefull.com/plans"
target="_blank"
rel="noreferrer"
onClick={() => {
sendMB('promo-click', eventSegmentation)
}}
>
<WritefullLogo width="16" height="16" />{' '}
<span>Get Writefull Premium</span>
</a>
}
/>
)
}
export default memo(WritefullPremiumPromoBanner)
@@ -62,6 +62,7 @@ function WritefullPromoBanner({
height={16}
width={16}
style={{ marginRight: 4 }}
aria-hidden="true"
/>
<span>Get Writefull for Overleaf</span>
</a>
@@ -1,14 +1,14 @@
function WritefullLogo() {
function WritefullLogo({ width = '40', height = '40' }) {
return (
<svg
width="40"
height="40"
width={width}
height={height}
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
style={{ verticalAlign: 'middle' }}
>
<rect width="40" height="40" fill="white" />
<rect
x="1.6665"
y="1.66666"