Merge pull request #19150 from overleaf/jdt-ai-promo

feat: add labs ai experiment promo
GitOrigin-RevId: 9bf039635b487339caa277b501a8cd99c7c7613f
This commit is contained in:
Jimmy Domagala-Tang 2024-07-02 08:10:22 -04:00 committed by Copybot
parent 8b41d26750
commit c0f39267a9
6 changed files with 73 additions and 1 deletions

View file

@ -117,7 +117,7 @@ async function projectListPage(req, res, next) {
}) })
const user = await User.findById( const user = await User.findById(
userId, userId,
`email emails features alphaProgram betaProgram lastPrimaryEmailCheck signUpDate${ `email emails features alphaProgram betaProgram lastPrimaryEmailCheck labsProgram signUpDate${
isSaas ? ' enrollment writefull' : '' isSaas ? ' enrollment writefull' : ''
}` }`
) )
@ -462,6 +462,7 @@ async function projectListPage(req, res, next) {
groupName: subscription.teamName, groupName: subscription.teamName,
})), })),
hasIndividualRecurlySubscription, hasIndividualRecurlySubscription,
userRestrictions: Array.from(req.userRestrictions || []),
}) })
} }

View file

@ -483,6 +483,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
'/project', '/project',
AuthenticationController.requireLogin(), AuthenticationController.requireLogin(),
RateLimiterMiddleware.rateLimit(rateLimiters.openDashboard), RateLimiterMiddleware.rateLimit(rateLimiters.openDashboard),
PermissionsController.useCapabilities(),
ProjectListController.projectListPage ProjectListController.projectListPage
) )
webRouter.post( webRouter.post(

View file

@ -468,6 +468,7 @@
"get_collaborative_benefits": "", "get_collaborative_benefits": "",
"get_discounted_plan": "", "get_discounted_plan": "",
"get_dropbox_sync": "", "get_dropbox_sync": "",
"get_early_access_to_ai": "",
"get_exclusive_access_to_labs": "", "get_exclusive_access_to_labs": "",
"get_full_project_history": "", "get_full_project_history": "",
"get_git_integration": "", "get_git_integration": "",

View file

@ -0,0 +1,66 @@
import { memo, useCallback, useState } from 'react'
import Notification from './notification'
import customLocalStorage from '@/infrastructure/local-storage'
import OLButton from '@/features/ui/components/ol/ol-button'
import getMeta from '@/utils/meta'
import * as eventTracking from '../../../../infrastructure/event-tracking'
import { useTranslation } from 'react-i18next'
function LabsAiPromoBanner() {
const user = getMeta('ol-user')
const cannotUseAi = getMeta('ol-cannot-use-ai')
const { t } = useTranslation()
const [show, setShow] = useState(() => {
const dismissed = customLocalStorage.getItem(
'has_dismissed_labs_ai_promo_banner'
)
if (dismissed || cannotUseAi) {
return false
}
const show = user?.labsProgram === true && !user?.features?.aiErrorAssistant
return show
})
const handleClose = useCallback(() => {
eventTracking.sendMB('promo-dismiss', {
name: 'labs-ai-experiment-promo',
})
customLocalStorage.setItem('has_dismissed_labs_ai_promo_banner', true)
setShow(false)
}, [setShow])
const handleClick = useCallback(() => {
eventTracking.sendMB('promo-click', {
name: 'labs-ai-experiment-promo',
content: 'try-now',
})
customLocalStorage.setItem('has_dismissed_labs_ai_promo_banner', true)
}, [])
if (!show) {
return null
}
return (
<div>
<Notification
type="info"
onDismiss={handleClose}
content={<span>{t('get_early_access_to_ai')}</span>}
action={
<OLButton
variant="secondary"
href="/labs/participate"
onClick={handleClick}
>
{t('try_now')}
</OLButton>
}
/>
</div>
)
}
export default memo(LabsAiPromoBanner)

View file

@ -12,6 +12,7 @@ import customLocalStorage from '../../../../infrastructure/local-storage'
import { sendMB } from '../../../../infrastructure/event-tracking' import { sendMB } from '../../../../infrastructure/event-tracking'
import GeoBanners from './geo-banners' import GeoBanners from './geo-banners'
import AccessibilitySurveyBanner from './accessibility-survey-banner' import AccessibilitySurveyBanner from './accessibility-survey-banner'
import LabsAiPromoBanner from './labs-ai-promo-banner'
const [enrollmentNotificationModule] = importOverleafModules( const [enrollmentNotificationModule] = importOverleafModules(
'managedGroupSubscriptionEnrollmentNotification' 'managedGroupSubscriptionEnrollmentNotification'
@ -79,6 +80,7 @@ function UserNotifications() {
setDismissedWritefull(true) setDismissedWritefull(true)
}} }}
/> />
<LabsAiPromoBanner />
</ul> </ul>
</div> </div>
) )

View file

@ -702,6 +702,7 @@
"get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline", "get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline",
"get_discounted_plan": "Get discounted plan", "get_discounted_plan": "Get discounted plan",
"get_dropbox_sync": "Get Dropbox Sync", "get_dropbox_sync": "Get Dropbox Sync",
"get_early_access_to_ai": "Get early access to the new AI Error Assistant in Overleaf Labs",
"get_exclusive_access_to_labs": "Get exclusive access to early-stage experiments when you join Overleaf Labs. All we ask in return is your honest feedback to help us develop and improve.", "get_exclusive_access_to_labs": "Get exclusive access to early-stage experiments when you join Overleaf Labs. All we ask in return is your honest feedback to help us develop and improve.",
"get_full_project_history": "Get full project history", "get_full_project_history": "Get full project history",
"get_git_integration": "Get Git integration", "get_git_integration": "Get Git integration",