diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.js b/services/web/app/src/Features/Subscription/SubscriptionController.js
index 07a5454be6..838b580273 100644
--- a/services/web/app/src/Features/Subscription/SubscriptionController.js
+++ b/services/web/app/src/Features/Subscription/SubscriptionController.js
@@ -154,6 +154,9 @@ async function userSubscriptionPage(req, res) {
)
}
+ const hasAiAssistViaWritefull =
+ await FeaturesUpdater.promises.hasFeaturesViaWritefull(user._id)
+
const data = {
title: 'your_subscription',
plans: plansData?.plans,
@@ -176,6 +179,7 @@ async function userSubscriptionPage(req, res) {
groupSettingsEnabledFor,
isManagedAccount: !!req.managedBy,
userRestrictions: Array.from(req.userRestrictions || []),
+ hasAiAssistViaWritefull,
}
res.render('subscriptions/dashboard-react', data)
}
@@ -322,13 +326,13 @@ async function previewAddonPurchase(req, res) {
subscriptionChange =
await SubscriptionHandler.promises.previewAddonPurchase(userId, addOnCode)
- const hasBundleViaWritefull =
+ const hasAiAssistViaWritefull =
await FeaturesUpdater.promises.hasFeaturesViaWritefull(userId)
const isAiUpgrade =
PaymentProviderEntities.subscriptionChangeIsAiAssistUpgrade(
subscriptionChange
)
- if (hasBundleViaWritefull && isAiUpgrade) {
+ if (hasAiAssistViaWritefull && isAiUpgrade) {
return res.redirect(
'/user/subscription?redirect-reason=writefull-entitled'
)
diff --git a/services/web/app/views/subscriptions/dashboard-react.pug b/services/web/app/views/subscriptions/dashboard-react.pug
index 6fac08dd53..dab505e4e5 100644
--- a/services/web/app/views/subscriptions/dashboard-react.pug
+++ b/services/web/app/views/subscriptions/dashboard-react.pug
@@ -1,33 +1,34 @@
extends ../layout-react
block entrypointVar
- - entrypoint = 'pages/user/subscription/dashboard'
+ - entrypoint = 'pages/user/subscription/dashboard'
block head-scripts
- script(type="text/javascript", nonce=scriptNonce, src="https://js.recurly.com/v4/recurly.js")
+ script(type="text/javascript", nonce=scriptNonce, src="https://js.recurly.com/v4/recurly.js")
block append meta
- meta(name="ol-subscription" data-type="json" content=personalSubscription)
- meta(name="ol-userCanExtendTrial" data-type="boolean" content=userCanExtendTrial)
- meta(name="ol-managedGroupSubscriptions" data-type="json" content=managedGroupSubscriptions)
- meta(name="ol-memberGroupSubscriptions" data-type="json" content=memberGroupSubscriptions)
- meta(name="ol-managedInstitutions" data-type="json" content=managedInstitutions)
- meta(name="ol-managedPublishers" data-type="json" content=managedPublishers)
- meta(name="ol-planCodesChangingAtTermEnd" data-type="json", content=planCodesChangingAtTermEnd)
- meta(name="ol-currentInstitutionsWithLicence" data-type="json" content=currentInstitutionsWithLicence)
- meta(name="ol-hasSubscription" data-type="boolean" content=hasSubscription)
- meta(name="ol-fromPlansPage" data-type="boolean" content=fromPlansPage)
- meta(name="ol-plans", data-type="json" content=plans)
- meta(name="ol-groupSettingsAdvertisedFor", data-type="json" content=groupSettingsAdvertisedFor)
- meta(name="ol-canUseFlexibleLicensing", data-type="boolean", content=canUseFlexibleLicensing)
- meta(name="ol-showGroupDiscount", data-type="boolean", content=showGroupDiscount)
- meta(name="ol-groupSettingsEnabledFor", data-type="json" content=groupSettingsEnabledFor)
- meta(name="ol-user" data-type="json" content=user)
- if (personalSubscription && personalSubscription.payment)
- meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
- meta(name="ol-recommendedCurrency" content=personalSubscription.payment.currency)
- meta(name="ol-groupPlans" data-type="json" content=groupPlans)
+ meta(name="ol-subscription" data-type="json" content=personalSubscription)
+ meta(name="ol-userCanExtendTrial" data-type="boolean" content=userCanExtendTrial)
+ meta(name="ol-managedGroupSubscriptions" data-type="json" content=managedGroupSubscriptions)
+ meta(name="ol-memberGroupSubscriptions" data-type="json" content=memberGroupSubscriptions)
+ meta(name="ol-managedInstitutions" data-type="json" content=managedInstitutions)
+ meta(name="ol-managedPublishers" data-type="json" content=managedPublishers)
+ meta(name="ol-planCodesChangingAtTermEnd" data-type="json", content=planCodesChangingAtTermEnd)
+ meta(name="ol-currentInstitutionsWithLicence" data-type="json" content=currentInstitutionsWithLicence)
+ meta(name="ol-hasSubscription" data-type="boolean" content=hasSubscription)
+ meta(name="ol-fromPlansPage" data-type="boolean" content=fromPlansPage)
+ meta(name="ol-plans" data-type="json" content=plans)
+ meta(name="ol-groupSettingsAdvertisedFor" data-type="json" content=groupSettingsAdvertisedFor)
+ meta(name="ol-canUseFlexibleLicensing" data-type="boolean", content=canUseFlexibleLicensing)
+ meta(name="ol-showGroupDiscount" data-type="boolean", content=showGroupDiscount)
+ meta(name="ol-groupSettingsEnabledFor" data-type="json" content=groupSettingsEnabledFor)
+ meta(name="ol-hasAiAssistViaWritefull" data-type="boolean", content=hasAiAssistViaWritefull)
+ meta(name="ol-user" data-type="json" content=user)
+ if (personalSubscription && personalSubscription.payment)
+ meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
+ meta(name="ol-recommendedCurrency" content=personalSubscription.payment.currency)
+ meta(name="ol-groupPlans" data-type="json" content=groupPlans)
block content
- main.content.content-alt#main-content
- #subscription-dashboard-root
+ main.content.content-alt#main-content
+ #subscription-dashboard-root
diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json
index 0b09d21471..cec5c60ebb 100644
--- a/services/web/frontend/extracted-translations.json
+++ b/services/web/frontend/extracted-translations.json
@@ -103,6 +103,7 @@
"aggregate_changed": "",
"aggregate_to": "",
"agree_with_the_terms": "",
+ "ai_assist_in_overleaf_is_included_via_writefull": "",
"ai_assistance_to_help_you": "",
"ai_based_language_tools": "",
"ai_can_make_mistakes": "",
@@ -671,6 +672,7 @@
"go_to_pdf_location_in_code": "",
"go_to_settings": "",
"go_to_subscriptions": "",
+ "go_to_writefull": "",
"good_news_you_already_purchased_this_add_on": "",
"good_news_you_are_already_receiving_this_add_on_via_writefull": "",
"group_admin": "",
@@ -789,6 +791,7 @@
"include_results_from_your_reference_manager": "",
"include_results_from_your_x_account": "",
"include_the_error_message_and_ai_response": "",
+ "included_as_part_of_your_writefull_subscription": "",
"increase_indent": "",
"increased_compile_timeout": "",
"inline": "",
@@ -979,6 +982,7 @@
"manage_publisher_managers": "",
"manage_sessions": "",
"manage_subscription": "",
+ "manage_your_ai_assist_add_on": "",
"managed": "",
"managed_user_accounts": "",
"managed_user_invite_has_been_sent_to_email": "",
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active-new.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active-new.tsx
index 1fc21a0c3c..22291f499e 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active-new.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active-new.tsx
@@ -10,6 +10,7 @@ import { ConfirmChangePlanModal } from './change-plan/modals/confirm-change-plan
import { KeepCurrentPlanModal } from './change-plan/modals/keep-current-plan-modal'
import { ChangeToGroupModal } from './change-plan/modals/change-to-group-modal'
import { CancelAiAddOnModal } from '@/features/subscription/components/dashboard/states/active/change-plan/modals/cancel-ai-add-on-modal'
+import { WritefullBundleManagementModal } from '@/features/subscription/components/dashboard/states/active/change-plan/modals/writefull-bundle-management-modal'
import OLButton from '@/features/ui/components/ol/ol-button'
import isInFreeTrial from '../../../../util/is-in-free-trial'
import AddOns from '@/features/subscription/components/dashboard/states/active/add-ons'
@@ -71,6 +72,7 @@ export function ActiveSubscriptionNew({
}
const handlePlanChange = () => setModalIdShown('change-plan')
+ const handleManageOnWritefull = () => setModalIdShown('manage-on-writefull')
const handleCancelClick = (addOnCode: string) => {
if ([AI_STANDALONE_PLAN_CODE, AI_ADD_ON_CODE].includes(addOnCode)) {
setModalIdShown('cancel-ai-add-on')
@@ -248,6 +250,7 @@ export function ActiveSubscriptionNew({
subscription={subscription}
onStandalonePlan={onStandalonePlan}
handleCancelClick={handleCancelClick}
+ handleManageOnWritefull={handleManageOnWritefull}
/>
{t('you_dont_have_any_add_ons_on_your_account')}
)} diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/writefull-bundle-management-modal.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/writefull-bundle-management-modal.tsx new file mode 100644 index 0000000000..ef512ddec5 --- /dev/null +++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/writefull-bundle-management-modal.tsx @@ -0,0 +1,51 @@ +import { useTranslation } from 'react-i18next' +import { SubscriptionDashModalIds } from '../../../../../../../../../../types/subscription/dashboard/modal-ids' +import { useSubscriptionDashboardContext } from '../../../../../../context/subscription-dashboard-context' +import OLModal, { + OLModalBody, + OLModalFooter, + OLModalHeader, + OLModalTitle, +} from '@/features/ui/components/ol/ol-modal' +import OLButton from '@/features/ui/components/ol/ol-button' + +export function WritefullBundleManagementModal() { + const modalId: SubscriptionDashModalIds = 'manage-on-writefull' + const { t } = useTranslation() + const { handleCloseModal, modalIdShown } = useSubscriptionDashboardContext() + + if (modalIdShown !== modalId) return null + + return ( +{t('ai_assist_in_overleaf_is_included_via_writefull')}
+