diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.mjs b/services/web/app/src/Features/Subscription/SubscriptionController.mjs index a663aecf4c..a7eebd8871 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionController.mjs @@ -184,7 +184,7 @@ async function userSubscriptionPage(req, res) { res, 'combined-user-management' ) - + await SplitTestHandler.promises.getAssignment(req, res, 'plans-2026-phase-1') const groupPricingDiscount = await SplitTestHandler.promises.getAssignment( req, res, diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 37c38de041..b969e9c481 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -47,6 +47,7 @@ "accepted_invite": "", "accepting": "", "access_all_premium_features": "", + "access_all_premium_features_ai": "", "access_all_premium_features_including_more_collaborators_real_time_track_changes_and_a_longer_compile_time": "", "access_denied": "", "access_edit_your_projects": "", @@ -692,6 +693,7 @@ "get_discounted_plan": "", "get_early_access_with_ai_assist_add_on": "", "get_exclusive_access_to_labs": "", + "get_full_project_history": "", "get_in_touch": "", "get_language_suggestions": "", "get_more_compile_time": "", @@ -699,6 +701,7 @@ "get_most_subscription_by_checking_overleaf": "", "get_most_subscription_by_checking_overleaf_ai_writefull": "", "get_real_time_track_changes": "", + "get_unlimited_ai": "", "git": "", "git_authentication_token": "", "git_authentication_token_create_modal_info_1": "", @@ -1351,6 +1354,7 @@ "please_set_main_file": "", "please_try_again_in_a_few_moments": "", "please_wait": "", + "plus_additional_collaborators_and_more": "", "plus_additional_collaborators_document_history_track_changes_and_more": "", "plus_more": "", "plus_x_additional_licenses_for_a_total_of_y_licenses": "", @@ -1850,6 +1854,8 @@ "sync_to_dropbox": "", "sync_to_github": "", "sync_with_a_github_repository": "", + "sync_with_dropbox": "", + "sync_with_github": "", "synctex_error_recompile_and_try_again": "", "synctex_failed": "", "syntax_checks": "", @@ -2078,6 +2084,7 @@ "university_school": "", "unknown": "", "unknown_group": "", + "unlimited_ai": "", "unlimited_ai_use": "", "unlimited_collaborators_per_project": "", "unlimited_collabs": "", @@ -2123,6 +2130,7 @@ "upgrade_plan": "", "upgrade_summary": "", "upgrade_to_add_more_collaborators_and_access_collaboration_features": "", + "upgrade_to_add_more_collaborators_and_more": "", "upgrade_to_get_feature": "", "upgrade_to_review": "", "upgrade_your_subscription": "", @@ -2240,6 +2248,7 @@ "why_not_pause_instead": "", "wide": "", "will_lose_edit_access_on_date": "", + "with_overleaf_subscription_you_also_get": "", "with_premium_subscription_you_also_get": "", "word_count_lower": "", "words": "", @@ -2273,6 +2282,7 @@ "you_are_on_a_paid_plan_contact_support_to_find_out_more": "", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "", + "you_are_using_our_free_plan": "", "you_can_also_choose_to_view_anonymously_or_leave_the_project": "", "you_can_also_right_click_a_file_to_set_it_as_main": "", "you_can_buy_this_plan_but_not_as_a_trial": "", 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 f4c528670c..cdc7d16bad 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 plans2026 = useFeatureFlag('plans-2026-phase-1') useEffect(() => { eventTracking.send('subscription-funnel', 'editor-click-feature', 'history') @@ -19,7 +21,9 @@ export function OwnerPaywallPrompt() { return (
-

{t('premium_feature')}

+

+ {plans2026 ? t('get_full_project_history') : t('premium_feature')} +

{t('currently_seeing_only_24_hrs_history')}

@@ -32,9 +36,7 @@ export function OwnerPaywallPrompt() { source="history" buttonProps={{ variant: 'premium' }} handleClick={handleFreeTrialClick} - > - {t('start_free_trial')} - + />

{clickedFreeTrialButton ? (

{t('refresh_page_after_starting_free_trial')}

diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx index 2e08212699..95b66f4ee2 100644 --- a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx +++ b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx @@ -8,10 +8,10 @@ import getMeta from '@/utils/meta' import { populateEditorRedesignSegmentation } from '@/shared/hooks/use-editor-analytics' import CompileTimeoutPaywallModal from '@/features/pdf-preview/components/compile-timeout-paywall-modal' import { isSplitTestEnabled } from '@/utils/splitTestUtils' +import { useFeatureFlag } from '@/shared/context/split-test-context' function TimeoutUpgradePromptNew() { const { isProjectOwner } = useDetachCompileContext() - const isCompileTimeoutTargetPlansEnabled = isSplitTestEnabled( 'compile-timeout-target-plans' ) @@ -61,6 +61,7 @@ const CompileTimeout = memo(function CompileTimeout({ isCompileTimeoutTargetPlansEnabled, }: CompileTimeoutProps) { const { t } = useTranslation() + const plans2026 = useFeatureFlag('plans-2026-phase-1') const extraSearchParams = useMemo(() => { return { itm_content: 'new-editor', @@ -93,9 +94,11 @@ const CompileTimeout = memo(function CompileTimeout({ {isProjectOwner ? (

{t('upgrade_for_more_compile_time')}{' '} - {t( - 'plus_additional_collaborators_document_history_track_changes_and_more' - )} + {plans2026 + ? t('plus_additional_collaborators_and_more') + : t( + 'plus_additional_collaborators_document_history_track_changes_and_more' + )}

) : ( (
  • @@ -94,7 +98,7 @@ function UpgradeTrackChangesModal() { }) } > - {t('try_it_for_free')} + {plans2026 ? t('try_for_free') : t('try_it_for_free')} ) : ( @@ -18,9 +20,11 @@ export default function CollaboratorsLimitUpgrade() { title={t('add_more_collaborators')} content={

    - {t( - 'upgrade_to_add_more_collaborators_and_access_collaboration_features' - )} + {plans2026 + ? t('upgrade_to_add_more_collaborators_and_more') + : t( + 'upgrade_to_add_more_collaborators_and_access_collaboration_features' + )}

    } isActionBelowContent diff --git a/services/web/frontend/js/features/subscription/components/dashboard/free-plan.tsx b/services/web/frontend/js/features/subscription/components/dashboard/free-plan.tsx index 1f9583dd8b..df418d0523 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/free-plan.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/free-plan.tsx @@ -1,30 +1,39 @@ import { useTranslation, Trans } from 'react-i18next' import WritefullManagedBundleAddOn from '@/features/subscription/components/dashboard/states/active/change-plan/modals/writefull-bundle-management-modal' import getMeta from '@/utils/meta' +import { useFeatureFlag } from '@/shared/context/split-test-context' function FreePlan() { const { t } = useTranslation() const hasAiAssistViaWritefull = getMeta('ol-hasAiAssistViaWritefull') - + const plans2026 = useFeatureFlag('plans-2026-phase-1') return ( <> - , - ]} - /> + {plans2026 ? ( + t('you_are_using_our_free_plan') + ) : ( + , + ]} + /> + )} :
    • {t('invite_more_collabs')}
    • -
    • {t('realtime_track_changes')}
    • + {plans2026 &&
    • {t('get_unlimited_ai')}
    • } + {!plans2026 &&
    • {t('realtime_track_changes')}
    • }
    • {t('full_doc_history')}
    • {t('reference_search')}
    • {t('reference_sync')}
    • {t('dropbox_integration_lowercase')}
    • {t('github_integration_lowercase')}
    • -
    • {t('priority_support')}
    • + {!plans2026 &&
    • {t('priority_support')}
    • }
    {t('upgrade_now')} diff --git a/services/web/frontend/js/shared/components/start-free-trial-button.tsx b/services/web/frontend/js/shared/components/start-free-trial-button.tsx index d461da9750..01697cba28 100644 --- a/services/web/frontend/js/shared/components/start-free-trial-button.tsx +++ b/services/web/frontend/js/shared/components/start-free-trial-button.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next' import { startFreeTrial } from '@/main/account-upgrade' import * as eventTracking from '../../infrastructure/event-tracking' import OLButton from '@/shared/components/ol/ol-button' +import { useFeatureFlag } from '@/shared/context/split-test-context' type StartFreeTrialButtonProps = { source: string @@ -26,6 +27,7 @@ export default function StartFreeTrialButton({ extraSearchParams, }: StartFreeTrialButtonProps) { const { t } = useTranslation() + const plans2026 = useFeatureFlag('plans-2026-phase-1') useEffect(() => { const eventSegmentation: { [key: string]: unknown } = { @@ -64,7 +66,10 @@ export default function StartFreeTrialButton({ return ( - {children || t('start_free_trial')} + {children || + (plans2026 + ? t('start_free_trial_without_exclamation') + : t('start_free_trial'))} ) } diff --git a/services/web/frontend/js/shared/components/upgrade-benefits.tsx b/services/web/frontend/js/shared/components/upgrade-benefits.tsx index 9ab3d01e86..02962959a7 100644 --- a/services/web/frontend/js/shared/components/upgrade-benefits.tsx +++ b/services/web/frontend/js/shared/components/upgrade-benefits.tsx @@ -2,6 +2,7 @@ import MaterialIcon from '@/shared/components/material-icon' import { useTranslation } from 'react-i18next' import { memo } from 'react' import classNames from 'classnames' +import { useFeatureFlag } from '@/shared/context/split-test-context' function Check() { return @@ -9,13 +10,14 @@ function Check() { function UpgradeBenefits({ className }: { className?: string }) { const { t } = useTranslation() + const plans2026 = useFeatureFlag('plans-2026-phase-1') return (