mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #12007 from overleaf/ii-react-subscription-dash-thank-you
[web] Successful subscription react migration GitOrigin-RevId: 1d7d849415f4b7a7f60ddf8a4e18570ff5142196
This commit is contained in:
parent
fc9955e719
commit
48587a7a62
8 changed files with 212 additions and 1 deletions
|
@ -367,6 +367,7 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
|
|||
res.locals.ExposedSettings = {
|
||||
isOverleaf: Settings.overleaf != null,
|
||||
appName: Settings.appName,
|
||||
adminEmail: Settings.adminEmail,
|
||||
dropboxAppName:
|
||||
Settings.apis.thirdPartyDataStore?.dropboxAppName || 'Overleaf',
|
||||
hasSamlBeta: req.session.samlBeta,
|
||||
|
|
|
@ -3,5 +3,9 @@ extends ../layout-marketing
|
|||
block entrypointVar
|
||||
- entrypoint = 'pages/user/subscription/successful-subscription'
|
||||
|
||||
block append meta
|
||||
meta(name="ol-subscription" data-type="json" content=personalSubscription)
|
||||
meta(name="ol-postCheckoutRedirect" content=postCheckoutRedirect)
|
||||
|
||||
block content
|
||||
main.content.content-alt#subscription-success-root
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"add_or_remove_project_from_tag": "",
|
||||
"add_role_and_department": "",
|
||||
"add_to_folder": "",
|
||||
"add_your_first_group_member_now": "",
|
||||
"adding": "",
|
||||
"additional_licenses": "",
|
||||
"address_line_1": "",
|
||||
|
@ -338,6 +339,7 @@
|
|||
"have_more_days_to_try": "",
|
||||
"headers": "",
|
||||
"help": "",
|
||||
"help_improve_overleaf_fill_out_this_survey": "",
|
||||
"hide_document_preamble": "",
|
||||
"hide_outline": "",
|
||||
"history": "",
|
||||
|
@ -489,6 +491,7 @@
|
|||
"name": "",
|
||||
"navigate_log_source": "",
|
||||
"navigation": "",
|
||||
"need_anything_contact_us_at": "",
|
||||
"need_more_than_x_licenses": "",
|
||||
"need_to_add_new_primary_before_remove": "",
|
||||
"need_to_leave": "",
|
||||
|
@ -648,6 +651,7 @@
|
|||
"refresh_page_after_linking_dropbox": "",
|
||||
"refresh_page_after_starting_free_trial": "",
|
||||
"refreshing": "",
|
||||
"regards": "",
|
||||
"relink_your_account": "",
|
||||
"remote_service_error": "",
|
||||
"remove": "",
|
||||
|
@ -792,6 +796,8 @@
|
|||
"terminated": "",
|
||||
"tex_live_version": "",
|
||||
"thank_you_exclamation": "",
|
||||
"thanks_for_subscribing": "",
|
||||
"thanks_for_subscribing_you_help_sl": "",
|
||||
"thanks_settings_updated": "",
|
||||
"the_following_files_already_exist_in_this_project": "",
|
||||
"then_x_price_per_month": "",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import useWaitForI18n from '../../../../shared/hooks/use-wait-for-i18n'
|
||||
import { SubscriptionDashboardProvider } from '../../context/subscription-dashboard-context'
|
||||
import SuccessfulSubscription from './successful-subscription'
|
||||
|
||||
function Root() {
|
||||
const { isReady } = useWaitForI18n()
|
||||
|
@ -7,7 +9,11 @@ function Root() {
|
|||
return null
|
||||
}
|
||||
|
||||
return <h2>React Subscription Success</h2>
|
||||
return (
|
||||
<SubscriptionDashboardProvider>
|
||||
<SuccessfulSubscription />
|
||||
</SubscriptionDashboardProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default Root
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
import { useTranslation, Trans } from 'react-i18next'
|
||||
import { Col, Row } from 'react-bootstrap'
|
||||
import { PriceExceptions } from '../shared/price-exceptions'
|
||||
import PremiumFeaturesLink from '../dashboard/premium-features-link'
|
||||
import getMeta from '../../../../utils/meta'
|
||||
import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context'
|
||||
import { ExposedSettings } from '../../../../../../types/exposed-settings'
|
||||
|
||||
function SuccessfulSubscription() {
|
||||
const { t } = useTranslation()
|
||||
const { personalSubscription: subscription } =
|
||||
useSubscriptionDashboardContext()
|
||||
const postCheckoutRedirect = getMeta('ol-postCheckoutRedirect') as
|
||||
| string
|
||||
| undefined
|
||||
const { appName, adminEmail }: ExposedSettings = getMeta('ol-ExposedSettings')
|
||||
|
||||
if (!subscription || !('recurly' in subscription)) return null
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<Row>
|
||||
<Col md={8} mdOffset={2}>
|
||||
<div className="card">
|
||||
<div className="page-header">
|
||||
<h2>{t('thanks_for_subscribing')}</h2>
|
||||
</div>
|
||||
<div role="alert" className="alert alert-success">
|
||||
{subscription.recurly.trial_ends_at && (
|
||||
<>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="next_payment_of_x_collectected_on_y"
|
||||
values={{
|
||||
paymentAmmount: subscription.recurly.displayPrice,
|
||||
collectionDate: subscription.recurly.nextPaymentDueAt,
|
||||
}}
|
||||
components={[<strong />, <strong />]} // eslint-disable-line react/jsx-key
|
||||
/>
|
||||
</p>
|
||||
<PriceExceptions subscription={subscription} />
|
||||
</>
|
||||
)}
|
||||
<p>
|
||||
{t('to_modify_your_subscription_go_to')}
|
||||
<a href="/user/subscription" rel="noopener noreferrer">
|
||||
{t('manage_subscription')}.
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
{subscription.groupPlan && (
|
||||
<p>
|
||||
<a
|
||||
href={`/manage/groups/${subscription._id}/members`}
|
||||
className="btn btn-primary btn-large"
|
||||
>
|
||||
{t('add_your_first_group_member_now')}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
{t('thanks_for_subscribing_you_help_sl', {
|
||||
planName: subscription.plan.name,
|
||||
})}
|
||||
</p>
|
||||
<PremiumFeaturesLink />
|
||||
<p>
|
||||
{t('need_anything_contact_us_at')}
|
||||
<a href={`mailto:${adminEmail}`} rel="noopener noreferrer">
|
||||
{adminEmail}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="help_improve_overleaf_fill_out_this_survey"
|
||||
components={[
|
||||
// eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
|
||||
<a
|
||||
href="https://forms.gle/CdLNX9m6NLxkv1yr5"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
{t('regards')},
|
||||
<br />
|
||||
The {appName} Team
|
||||
</p>
|
||||
<p>
|
||||
<a
|
||||
className="btn btn-primary"
|
||||
href={postCheckoutRedirect || '/project'}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
< {t('back_to_your_projects')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SuccessfulSubscription
|
|
@ -124,6 +124,7 @@ const initialize = () => {
|
|||
window.user = user
|
||||
|
||||
window.ExposedSettings = {
|
||||
adminEmail: 'placeholder@example.com',
|
||||
appName: 'Overleaf',
|
||||
cookieDomain: '.overleaf.stories',
|
||||
dropboxAppName: 'Overleaf-Stories',
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
import { expect } from 'chai'
|
||||
import { screen, within } from '@testing-library/react'
|
||||
import SuccessfulSubscription from '../../../../../../frontend/js/features/subscription/components/successful-subscription/successful-subscription'
|
||||
import { renderWithSubscriptionDashContext } from '../../helpers/render-with-subscription-dash-context'
|
||||
import { annualActiveSubscription } from '../../fixtures/subscriptions'
|
||||
|
||||
describe('successful subscription page', function () {
|
||||
afterEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
})
|
||||
|
||||
it('renders the invoices link', function () {
|
||||
const adminEmail = 'foo@example.com'
|
||||
const options = {
|
||||
metaTags: [
|
||||
{
|
||||
name: 'ol-ExposedSettings',
|
||||
value: {
|
||||
adminEmail,
|
||||
},
|
||||
},
|
||||
{ name: 'ol-subscription', value: annualActiveSubscription },
|
||||
],
|
||||
}
|
||||
renderWithSubscriptionDashContext(<SuccessfulSubscription />, options)
|
||||
|
||||
screen.getByRole('heading', { name: /thanks for subscribing/i })
|
||||
const alert = screen.getByRole('alert')
|
||||
within(alert).getByText(/to modify your subscription go to/i)
|
||||
const manageSubscriptionLink = within(alert).getByRole('link', {
|
||||
name: /manage subscription/i,
|
||||
})
|
||||
expect(manageSubscriptionLink.getAttribute('href')).to.equal(
|
||||
'/user/subscription'
|
||||
)
|
||||
screen.getByText(
|
||||
`Thank you for subscribing to the ${annualActiveSubscription.plan.name} plan.`,
|
||||
{ exact: false }
|
||||
)
|
||||
screen.getByText(
|
||||
/it’s support from people like yourself that allows .* to continue to grow and improve/i
|
||||
)
|
||||
expect(screen.getByText(/get the most out of your/i).textContent).to.match(
|
||||
/get the most out of your .* subscription by checking out the list of .*’s premium features/i
|
||||
)
|
||||
expect(
|
||||
screen
|
||||
.getByText(/if there is anything you ever/i)
|
||||
.textContent?.replace(/\xA0/g, ' ')
|
||||
).to.equal(
|
||||
`If there is anything you ever need please feel free to contact us directly at ${adminEmail}.`
|
||||
)
|
||||
|
||||
const contactLink = screen.getByRole('link', {
|
||||
name: adminEmail,
|
||||
})
|
||||
expect(contactLink.getAttribute('href')).to.equal(`mailto:${adminEmail}`)
|
||||
|
||||
expect(
|
||||
screen.getByText(/if you would like to help us improve/i).textContent
|
||||
).to.match(
|
||||
/if you would like to help us improve .*, please take a moment to fill out this survey/i
|
||||
)
|
||||
|
||||
const surveyLink = screen.getByRole('link', {
|
||||
name: /this survey/i,
|
||||
})
|
||||
expect(surveyLink.getAttribute('href')).to.equal(
|
||||
'https://forms.gle/CdLNX9m6NLxkv1yr5'
|
||||
)
|
||||
|
||||
const helpLink = screen.getByRole('link', {
|
||||
name: /.*’s premium features/i,
|
||||
})
|
||||
expect(helpLink.getAttribute('href')).to.equal(
|
||||
'/learn/how-to/Overleaf_premium_features'
|
||||
)
|
||||
|
||||
const backToYourProjectsLink = screen.getByRole('link', {
|
||||
name: /back to your projects/i,
|
||||
})
|
||||
expect(backToYourProjectsLink.getAttribute('href')).to.equal('/project')
|
||||
})
|
||||
})
|
|
@ -5,6 +5,7 @@ type TemplateLink = {
|
|||
}
|
||||
|
||||
export type ExposedSettings = {
|
||||
adminEmail: string
|
||||
appName: string
|
||||
cookieDomain: string
|
||||
dropboxAppName: string
|
||||
|
|
Loading…
Reference in a new issue