diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs index bcfce8c0e8..62201b4dde 100644 --- a/services/web/app/src/Features/Project/ProjectController.mjs +++ b/services/web/app/src/Features/Project/ProjectController.mjs @@ -518,7 +518,7 @@ const _ProjectController = { user: (async () => { const user = await User.findById( userId, - 'email first_name last_name referal_id signUpDate featureSwitches features featuresEpoch refProviders alphaProgram betaProgram isAdmin ace labsProgram labsExperiments completedTutorials writefull aiFeatures' + 'email first_name last_name referal_id signUpDate featureSwitches features featuresEpoch refProviders alphaProgram betaProgram isAdmin ace labsProgram labsExperiments completedTutorials writefull aiFeatures lastTrial' ).exec() // Handle case of deleted user if (!user) { @@ -627,19 +627,26 @@ const _ProjectController = { inEnterpriseCommons || affiliation.institution?.enterpriseCommons } - const getSplitTestAssignment = async splitTest => { - return await SplitTestHandler.promises.getAssignment( - req, - res, - splitTest - ) + const allowedFreeTrial = + subscription == null || + isStandaloneAiAddOnPlanCode(subscription.planCode) + + // The test's audience: free users who've spent their trial and can't start + // another, yet still see a misleading "free trial" CTA. + const trialIneligible = + !anonymous && allowedFreeTrial && Boolean(user?.lastTrial) + + if (trialIneligible) { + splitTests.push('paywall-cta-trial-ineligible') } - const splitTestAssignments = {} - await Promise.all( - splitTests.map(async splitTest => { - splitTestAssignments[splitTest] = - await getSplitTestAssignment(splitTest) - }) + + const splitTestAssignments = Object.fromEntries( + await Promise.all( + splitTests.map(async splitTest => [ + splitTest, + await SplitTestHandler.promises.getAssignment(req, res, splitTest), + ]) + ) ) // PDF caching, these tests are archived but we are keeping the frontend code unchanged for now @@ -705,10 +712,6 @@ const _ProjectController = { return res.sendStatus(401) } - const allowedFreeTrial = - subscription == null || - isStandaloneAiAddOnPlanCode(subscription.planCode) - let wsUrl = Settings.wsUrl let metricName = 'load-editor-ws' if (user.betaProgram && Settings.wsUrlBeta !== undefined) { diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 8cfbe5b80b..8ba98a65db 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1631,6 +1631,7 @@ "refresh": "", "refresh_page_after_linking_dropbox": "", "refresh_page_after_starting_free_trial": "", + "refresh_page_after_subscribing": "", "refreshing": "", "refund_with_description": "", "regards": "", diff --git a/services/web/frontend/js/features/history/components/change-list/owner-paywall-prompt.tsx b/services/web/frontend/js/features/history/components/change-list/owner-paywall-prompt.tsx index 0a8d0e6a75..c26018aafd 100644 --- a/services/web/frontend/js/features/history/components/change-list/owner-paywall-prompt.tsx +++ b/services/web/frontend/js/features/history/components/change-list/owner-paywall-prompt.tsx @@ -3,10 +3,12 @@ import { useCallback, useEffect, useState } from 'react' import * as eventTracking from '../../../../infrastructure/event-tracking' import StartFreeTrialButton from '../../../../shared/components/start-free-trial-button' import UpgradeBenefits from '@/shared/components/upgrade-benefits' +import { useFeatureFlag } from '@/shared/context/split-test-context' export function OwnerPaywallPrompt() { const { t } = useTranslation() const [clickedFreeTrialButton, setClickedFreeTrialButton] = useState(false) + const showSubscribeNow = useFeatureFlag('paywall-cta-trial-ineligible') useEffect(() => { eventTracking.send('subscription-funnel', 'editor-click-feature', 'history') @@ -34,11 +36,15 @@ export function OwnerPaywallPrompt() { buttonProps={{ variant: 'premium' }} handleClick={handleFreeTrialClick} > - {t('start_free_trial')} + {showSubscribeNow ? t('subscribe_now') : t('start_free_trial')}
{clickedFreeTrialButton ? ( -{t('refresh_page_after_starting_free_trial')}
++ {showSubscribeNow + ? t('refresh_page_after_subscribing') + : t('refresh_page_after_starting_free_trial')} +
) : null} ) diff --git a/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx index ff49e7cd4e..7561e74cee 100644 --- a/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx +++ b/services/web/frontend/js/features/pdf-preview/components/compile-time-warning-upgrade-prompt-inner.tsx @@ -3,12 +3,14 @@ import StartFreeTrialButton from '@/shared/components/start-free-trial-button' import * as eventTracking from '../../../infrastructure/event-tracking' import { useTranslation } from 'react-i18next' import { FC } from 'react' +import { useFeatureFlag } from '@/shared/context/split-test-context' export const CompileTimeWarningUpgradePromptInner: FC<{ handleDismissWarning: () => void segmentation: eventTracking.Segmentation }> = ({ handleDismissWarning, segmentation }) => { const { t } = useTranslation() + const showSubscribeNow = useFeatureFlag('paywall-cta-trial-ineligible') return (